Merge pull request #545 from openboard-team/feature-one-handed-mode
One-handed mode feature
6
.github/workflows/android-build.yml
vendored
|
@ -25,13 +25,13 @@ jobs:
|
||||||
run: chmod +x gradlew
|
run: chmod +x gradlew
|
||||||
|
|
||||||
- name: Build with Gradle
|
- name: Build with Gradle
|
||||||
run: ./gradlew build
|
run: ./gradlew assembleDebug
|
||||||
|
|
||||||
- name: Upload our APK
|
- name: Upload APK
|
||||||
uses: actions/upload-artifact@v2.2.0
|
uses: actions/upload-artifact@v2.2.0
|
||||||
with:
|
with:
|
||||||
name: APK
|
name: APK
|
||||||
path: app/build/outputs/apk/release/app-release-unsigned.apk
|
path: app/build/outputs/apk/debug/app-debug.apk
|
||||||
|
|
||||||
- name: Upload lint report
|
- name: Upload lint report
|
||||||
uses: actions/upload-artifact@v2.2.0
|
uses: actions/upload-artifact@v2.2.0
|
||||||
|
|
|
@ -85,6 +85,7 @@ public final class KeyboardId {
|
||||||
public final String mCustomActionLabel;
|
public final String mCustomActionLabel;
|
||||||
public final boolean mHasShortcutKey;
|
public final boolean mHasShortcutKey;
|
||||||
public final boolean mIsSplitLayout;
|
public final boolean mIsSplitLayout;
|
||||||
|
public final boolean mOneHandedModeEnabled;
|
||||||
|
|
||||||
private final int mHashCode;
|
private final int mHashCode;
|
||||||
|
|
||||||
|
@ -103,6 +104,7 @@ public final class KeyboardId {
|
||||||
? mEditorInfo.actionLabel.toString() : null;
|
? mEditorInfo.actionLabel.toString() : null;
|
||||||
mHasShortcutKey = params.mVoiceInputKeyEnabled;
|
mHasShortcutKey = params.mVoiceInputKeyEnabled;
|
||||||
mIsSplitLayout = params.mIsSplitLayoutEnabled;
|
mIsSplitLayout = params.mIsSplitLayoutEnabled;
|
||||||
|
mOneHandedModeEnabled = params.mOneHandedModeEnabled;
|
||||||
|
|
||||||
mHashCode = computeHashCode(this);
|
mHashCode = computeHashCode(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,7 @@ public final class KeyboardLayoutSet {
|
||||||
boolean mNumberRowEnabled;
|
boolean mNumberRowEnabled;
|
||||||
boolean mLanguageSwitchKeyEnabled;
|
boolean mLanguageSwitchKeyEnabled;
|
||||||
boolean mEmojiKeyEnabled;
|
boolean mEmojiKeyEnabled;
|
||||||
|
boolean mOneHandedModeEnabled;
|
||||||
RichInputMethodSubtype mSubtype;
|
RichInputMethodSubtype mSubtype;
|
||||||
boolean mIsSpellChecker;
|
boolean mIsSpellChecker;
|
||||||
int mKeyboardWidth;
|
int mKeyboardWidth;
|
||||||
|
@ -351,6 +352,11 @@ public final class KeyboardLayoutSet {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder setOneHandedModeEnabled(boolean enabled) {
|
||||||
|
mParams.mOneHandedModeEnabled = enabled;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
// Super redux version of reading the script ID for some subtype from Xml.
|
// Super redux version of reading the script ID for some subtype from Xml.
|
||||||
static int readScriptId(final Resources resources, final InputMethodSubtype subtype) {
|
static int readScriptId(final Resources resources, final InputMethodSubtype subtype) {
|
||||||
final String layoutSetName = KEYBOARD_LAYOUT_SET_RESOURCE_PREFIX
|
final String layoutSetName = KEYBOARD_LAYOUT_SET_RESOURCE_PREFIX
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.dslul.openboard.inputmethod.keyboard.emoji.EmojiPalettesView;
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardState;
|
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardState;
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardTextsSet;
|
import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardTextsSet;
|
||||||
import org.dslul.openboard.inputmethod.latin.InputView;
|
import org.dslul.openboard.inputmethod.latin.InputView;
|
||||||
|
import org.dslul.openboard.inputmethod.latin.KeyboardWrapperView;
|
||||||
import org.dslul.openboard.inputmethod.latin.LatinIME;
|
import org.dslul.openboard.inputmethod.latin.LatinIME;
|
||||||
import org.dslul.openboard.inputmethod.latin.R;
|
import org.dslul.openboard.inputmethod.latin.R;
|
||||||
import org.dslul.openboard.inputmethod.latin.RichInputMethodManager;
|
import org.dslul.openboard.inputmethod.latin.RichInputMethodManager;
|
||||||
|
@ -51,6 +52,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
private static final String TAG = KeyboardSwitcher.class.getSimpleName();
|
private static final String TAG = KeyboardSwitcher.class.getSimpleName();
|
||||||
|
|
||||||
private InputView mCurrentInputView;
|
private InputView mCurrentInputView;
|
||||||
|
private KeyboardWrapperView mKeyboardViewWrapper;
|
||||||
private View mMainKeyboardFrame;
|
private View mMainKeyboardFrame;
|
||||||
private MainKeyboardView mKeyboardView;
|
private MainKeyboardView mKeyboardView;
|
||||||
private EmojiPalettesView mEmojiPalettesView;
|
private EmojiPalettesView mEmojiPalettesView;
|
||||||
|
@ -117,7 +119,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(
|
final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(
|
||||||
mThemeContext, editorInfo);
|
mThemeContext, editorInfo);
|
||||||
final Resources res = mThemeContext.getResources();
|
final Resources res = mThemeContext.getResources();
|
||||||
final int keyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res);
|
final int keyboardWidth = ResourceUtils.getKeyboardWidth(res, settingsValues);
|
||||||
final int keyboardHeight = ResourceUtils.getKeyboardHeight(res, settingsValues);
|
final int keyboardHeight = ResourceUtils.getKeyboardHeight(res, settingsValues);
|
||||||
builder.setKeyboardGeometry(keyboardWidth, keyboardHeight);
|
builder.setKeyboardGeometry(keyboardWidth, keyboardHeight);
|
||||||
builder.setSubtype(mRichImm.getCurrentSubtype());
|
builder.setSubtype(mRichImm.getCurrentSubtype());
|
||||||
|
@ -127,9 +129,12 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
builder.setEmojiKeyEnabled(settingsValues.mShowsEmojiKey);
|
builder.setEmojiKeyEnabled(settingsValues.mShowsEmojiKey);
|
||||||
builder.setSplitLayoutEnabledByUser(ProductionFlags.IS_SPLIT_KEYBOARD_SUPPORTED
|
builder.setSplitLayoutEnabledByUser(ProductionFlags.IS_SPLIT_KEYBOARD_SUPPORTED
|
||||||
&& settingsValues.mIsSplitKeyboardEnabled);
|
&& settingsValues.mIsSplitKeyboardEnabled);
|
||||||
|
final boolean oneHandedModeEnabled = settingsValues.mOneHandedModeEnabled;
|
||||||
|
builder.setOneHandedModeEnabled(oneHandedModeEnabled);
|
||||||
mKeyboardLayoutSet = builder.build();
|
mKeyboardLayoutSet = builder.build();
|
||||||
try {
|
try {
|
||||||
mState.onLoadKeyboard(currentAutoCapsState, currentRecapitalizeState);
|
mState.onLoadKeyboard(currentAutoCapsState, currentRecapitalizeState,
|
||||||
|
oneHandedModeEnabled);
|
||||||
mKeyboardTextsSet.setLocale(mRichImm.getCurrentSubtypeLocale(), mThemeContext);
|
mKeyboardTextsSet.setLocale(mRichImm.getCurrentSubtypeLocale(), mThemeContext);
|
||||||
} catch (KeyboardLayoutSetException e) {
|
} catch (KeyboardLayoutSetException e) {
|
||||||
Log.w(TAG, "loading keyboard failed: " + e.mKeyboardId, e.getCause());
|
Log.w(TAG, "loading keyboard failed: " + e.mKeyboardId, e.getCause());
|
||||||
|
@ -424,6 +429,30 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implements {@link KeyboardState.SwitchActions}.
|
||||||
|
@Override
|
||||||
|
public void setOneHandedModeEnabled(boolean enabled) {
|
||||||
|
if (mKeyboardViewWrapper.getOneHandedModeEnabled() == enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Settings settings = Settings.getInstance();
|
||||||
|
mKeyboardViewWrapper.setOneHandedModeEnabled(enabled);
|
||||||
|
mKeyboardViewWrapper.setOneHandedGravity(settings.getCurrent().mOneHandedModeGravity);
|
||||||
|
|
||||||
|
settings.writeOneHandedModeEnabled(enabled);
|
||||||
|
|
||||||
|
// Reload the entire keyboard set with the same parameters
|
||||||
|
loadKeyboard(mLatinIME.getCurrentInputEditorInfo(), settings.getCurrent(),
|
||||||
|
mLatinIME.getCurrentAutoCapsState(), mLatinIME.getCurrentRecapitalizeState());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements {@link KeyboardState.SwitchActions}.
|
||||||
|
@Override
|
||||||
|
public void switchOneHandedMode() {
|
||||||
|
mKeyboardViewWrapper.switchOneHandedModeSide();
|
||||||
|
Settings.getInstance().writeOneHandedModeGravity(mKeyboardViewWrapper.getOneHandedGravity());
|
||||||
|
}
|
||||||
|
|
||||||
// Implements {@link KeyboardState.SwitchActions}.
|
// Implements {@link KeyboardState.SwitchActions}.
|
||||||
@Override
|
@Override
|
||||||
public boolean isInDoubleTapShiftKeyTimeout() {
|
public boolean isInDoubleTapShiftKeyTimeout() {
|
||||||
|
@ -476,7 +505,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
} else if (isShowingClipboardHistory()) {
|
} else if (isShowingClipboardHistory()) {
|
||||||
return mClipboardHistoryView;
|
return mClipboardHistoryView;
|
||||||
}
|
}
|
||||||
return mKeyboardView;
|
return mKeyboardViewWrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MainKeyboardView getMainKeyboardView() {
|
public MainKeyboardView getMainKeyboardView() {
|
||||||
|
@ -509,6 +538,8 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
mEmojiPalettesView = mCurrentInputView.findViewById(R.id.emoji_palettes_view);
|
mEmojiPalettesView = mCurrentInputView.findViewById(R.id.emoji_palettes_view);
|
||||||
mClipboardHistoryView = mCurrentInputView.findViewById(R.id.clipboard_history_view);
|
mClipboardHistoryView = mCurrentInputView.findViewById(R.id.clipboard_history_view);
|
||||||
|
|
||||||
|
mKeyboardViewWrapper = mCurrentInputView.findViewById(R.id.keyboard_view_wrapper);
|
||||||
|
mKeyboardViewWrapper.setKeyboardActionListener(mLatinIME);
|
||||||
mKeyboardView = mCurrentInputView.findViewById(R.id.keyboard_view);
|
mKeyboardView = mCurrentInputView.findViewById(R.id.keyboard_view);
|
||||||
mKeyboardView.setHardwareAcceleratedDrawingEnabled(isHardwareAcceleratedDrawingEnabled);
|
mKeyboardView.setHardwareAcceleratedDrawingEnabled(isHardwareAcceleratedDrawingEnabled);
|
||||||
mKeyboardView.setKeyboardActionListener(mLatinIME);
|
mKeyboardView.setKeyboardActionListener(mLatinIME);
|
||||||
|
|
|
@ -700,13 +700,16 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
|
||||||
final boolean countryCodeMatched = matchCountryCodes(caseAttr, locale);
|
final boolean countryCodeMatched = matchCountryCodes(caseAttr, locale);
|
||||||
final boolean splitLayoutMatched = matchBoolean(caseAttr,
|
final boolean splitLayoutMatched = matchBoolean(caseAttr,
|
||||||
R.styleable.Keyboard_Case_isSplitLayout, id.mIsSplitLayout);
|
R.styleable.Keyboard_Case_isSplitLayout, id.mIsSplitLayout);
|
||||||
|
final boolean oneHandedModeEnabledMatched = matchBoolean(caseAttr,
|
||||||
|
R.styleable.Keyboard_Case_oneHandedModeEnabled,
|
||||||
|
id.mOneHandedModeEnabled);
|
||||||
final boolean selected = keyboardLayoutSetMatched && keyboardLayoutSetElementMatched
|
final boolean selected = keyboardLayoutSetMatched && keyboardLayoutSetElementMatched
|
||||||
&& keyboardThemeMacthed && modeMatched && navigateNextMatched
|
&& keyboardThemeMacthed && modeMatched && navigateNextMatched
|
||||||
&& navigatePreviousMatched && passwordInputMatched && clobberSettingsKeyMatched
|
&& navigatePreviousMatched && passwordInputMatched && clobberSettingsKeyMatched
|
||||||
&& hasShortcutKeyMatched && numberRowEnabledMatched && languageSwitchKeyEnabledMatched
|
&& hasShortcutKeyMatched && numberRowEnabledMatched && languageSwitchKeyEnabledMatched
|
||||||
&& emojiKeyEnabledMatched && isMultiLineMatched && imeActionMatched && isIconDefinedMatched
|
&& emojiKeyEnabledMatched && isMultiLineMatched && imeActionMatched && isIconDefinedMatched
|
||||||
&& localeCodeMatched && languageCodeMatched && countryCodeMatched
|
&& localeCodeMatched && languageCodeMatched && countryCodeMatched
|
||||||
&& splitLayoutMatched;
|
&& splitLayoutMatched && oneHandedModeEnabledMatched;
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
startTag("<%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE,
|
startTag("<%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE,
|
||||||
|
@ -748,6 +751,8 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
|
||||||
"languageCode"),
|
"languageCode"),
|
||||||
textAttr(caseAttr.getString(R.styleable.Keyboard_Case_countryCode),
|
textAttr(caseAttr.getString(R.styleable.Keyboard_Case_countryCode),
|
||||||
"countryCode"),
|
"countryCode"),
|
||||||
|
booleanAttr(caseAttr, R.styleable.Keyboard_Case_oneHandedModeEnabled,
|
||||||
|
"oneHandedModeEnabled"),
|
||||||
selected ? "" : " skipped");
|
selected ? "" : " skipped");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,10 @@ public final class KeyboardCodesSet {
|
||||||
"key_alpha_from_emoji",
|
"key_alpha_from_emoji",
|
||||||
"key_unspecified",
|
"key_unspecified",
|
||||||
"key_clipboard",
|
"key_clipboard",
|
||||||
"key_alpha_from_clipboard"
|
"key_alpha_from_clipboard",
|
||||||
|
"key_start_onehanded",
|
||||||
|
"key_stop_onehanded",
|
||||||
|
"key_switch_onehanded"
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final int[] DEFAULT = {
|
private static final int[] DEFAULT = {
|
||||||
|
@ -76,7 +79,10 @@ public final class KeyboardCodesSet {
|
||||||
Constants.CODE_ALPHA_FROM_EMOJI,
|
Constants.CODE_ALPHA_FROM_EMOJI,
|
||||||
Constants.CODE_UNSPECIFIED,
|
Constants.CODE_UNSPECIFIED,
|
||||||
Constants.CODE_CLIPBOARD,
|
Constants.CODE_CLIPBOARD,
|
||||||
Constants.CODE_ALPHA_FROM_CLIPBOARD
|
Constants.CODE_ALPHA_FROM_CLIPBOARD,
|
||||||
|
Constants.CODE_START_ONE_HANDED_MODE,
|
||||||
|
Constants.CODE_STOP_ONE_HANDED_MODE,
|
||||||
|
Constants.CODE_SWITCH_ONE_HANDED_MODE
|
||||||
};
|
};
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
|
|
@ -62,6 +62,9 @@ public final class KeyboardIconsSet {
|
||||||
public static final String NAME_CLIPBOARD_ACTION_KEY = "clipboard_action_key";
|
public static final String NAME_CLIPBOARD_ACTION_KEY = "clipboard_action_key";
|
||||||
public static final String NAME_CLIPBOARD_NORMAL_KEY = "clipboard_normal_key";
|
public static final String NAME_CLIPBOARD_NORMAL_KEY = "clipboard_normal_key";
|
||||||
public static final String NAME_CLEAR_CLIPBOARD_KEY = "clear_clipboard_key";
|
public static final String NAME_CLEAR_CLIPBOARD_KEY = "clear_clipboard_key";
|
||||||
|
public static final String NAME_START_ONEHANDED_KEY = "start_onehanded_mode_key";
|
||||||
|
public static final String NAME_STOP_ONEHANDED_KEY = "stop_onehanded_mode_key";
|
||||||
|
public static final String NAME_SWITCH_ONEHANDED_KEY = "switch_onehanded_key";
|
||||||
|
|
||||||
private static final SparseIntArray ATTR_ID_TO_ICON_ID = new SparseIntArray();
|
private static final SparseIntArray ATTR_ID_TO_ICON_ID = new SparseIntArray();
|
||||||
|
|
||||||
|
@ -95,6 +98,9 @@ public final class KeyboardIconsSet {
|
||||||
NAME_CLIPBOARD_ACTION_KEY, R.styleable.Keyboard_iconClipboardActionKey,
|
NAME_CLIPBOARD_ACTION_KEY, R.styleable.Keyboard_iconClipboardActionKey,
|
||||||
NAME_CLIPBOARD_NORMAL_KEY, R.styleable.Keyboard_iconClipboardNormalKey,
|
NAME_CLIPBOARD_NORMAL_KEY, R.styleable.Keyboard_iconClipboardNormalKey,
|
||||||
NAME_CLEAR_CLIPBOARD_KEY, R.styleable.Keyboard_iconClearClipboardKey,
|
NAME_CLEAR_CLIPBOARD_KEY, R.styleable.Keyboard_iconClearClipboardKey,
|
||||||
|
NAME_START_ONEHANDED_KEY, R.styleable.Keyboard_iconStartOneHandedMode,
|
||||||
|
NAME_STOP_ONEHANDED_KEY, R.styleable.Keyboard_iconStopOneHandedMode,
|
||||||
|
NAME_SWITCH_ONEHANDED_KEY, R.styleable.Keyboard_iconSwitchOneHandedMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
private static int NUM_ICONS = NAMES_AND_ATTR_IDS.length / 2;
|
private static int NUM_ICONS = NAMES_AND_ATTR_IDS.length / 2;
|
||||||
|
|
|
@ -30,7 +30,7 @@ import org.dslul.openboard.inputmethod.latin.utils.RecapitalizeStatus;
|
||||||
*
|
*
|
||||||
* This class contains all keyboard state transition logic.
|
* This class contains all keyboard state transition logic.
|
||||||
*
|
*
|
||||||
* The input events are {@link #onLoadKeyboard(int, int)}, {@link #onSaveKeyboardState()},
|
* The input events are {@link #onLoadKeyboard(int, int, boolean)}, {@link #onSaveKeyboardState()},
|
||||||
* {@link #onPressKey(int,boolean,int,int)}, {@link #onReleaseKey(int,boolean,int,int)},
|
* {@link #onPressKey(int,boolean,int,int)}, {@link #onReleaseKey(int,boolean,int,int)},
|
||||||
* {@link #onEvent(Event,int,int)}, {@link #onFinishSlidingInput(int,int)},
|
* {@link #onEvent(Event,int,int)}, {@link #onFinishSlidingInput(int,int)},
|
||||||
* {@link #onUpdateShiftState(int,int)}, {@link #onResetKeyboardStateToAlphabet(int,int)}.
|
* {@link #onUpdateShiftState(int,int)}, {@link #onResetKeyboardStateToAlphabet(int,int)}.
|
||||||
|
@ -65,6 +65,9 @@ public final class KeyboardState {
|
||||||
void startDoubleTapShiftKeyTimer();
|
void startDoubleTapShiftKeyTimer();
|
||||||
boolean isInDoubleTapShiftKeyTimeout();
|
boolean isInDoubleTapShiftKeyTimeout();
|
||||||
void cancelDoubleTapShiftKeyTimer();
|
void cancelDoubleTapShiftKeyTimer();
|
||||||
|
|
||||||
|
void setOneHandedModeEnabled(boolean enabled);
|
||||||
|
void switchOneHandedMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final SwitchActions mSwitchActions;
|
private final SwitchActions mSwitchActions;
|
||||||
|
@ -130,7 +133,8 @@ public final class KeyboardState {
|
||||||
mRecapitalizeMode = RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE;
|
mRecapitalizeMode = RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onLoadKeyboard(final int autoCapsFlags, final int recapitalizeMode) {
|
public void onLoadKeyboard(final int autoCapsFlags, final int recapitalizeMode,
|
||||||
|
final boolean onHandedModeEnabled) {
|
||||||
if (DEBUG_EVENT) {
|
if (DEBUG_EVENT) {
|
||||||
Log.d(TAG, "onLoadKeyboard: " + stateToString(autoCapsFlags, recapitalizeMode));
|
Log.d(TAG, "onLoadKeyboard: " + stateToString(autoCapsFlags, recapitalizeMode));
|
||||||
}
|
}
|
||||||
|
@ -147,6 +151,7 @@ public final class KeyboardState {
|
||||||
// Reset keyboard to alphabet mode.
|
// Reset keyboard to alphabet mode.
|
||||||
setAlphabetKeyboard(autoCapsFlags, recapitalizeMode);
|
setAlphabetKeyboard(autoCapsFlags, recapitalizeMode);
|
||||||
}
|
}
|
||||||
|
mSwitchActions.setOneHandedModeEnabled(onHandedModeEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constants for {@link SavedKeyboardState#mShiftMode} and {@link #setShifted(int)}.
|
// Constants for {@link SavedKeyboardState#mShiftMode} and {@link #setShifted(int)}.
|
||||||
|
@ -368,6 +373,20 @@ public final class KeyboardState {
|
||||||
mSwitchActions.setClipboardKeyboard();
|
mSwitchActions.setClipboardKeyboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setOneHandedModeEnabled(boolean enabled) {
|
||||||
|
if (DEBUG_INTERNAL_ACTION) {
|
||||||
|
Log.d(TAG, "setOneHandedModeEnabled");
|
||||||
|
}
|
||||||
|
mSwitchActions.setOneHandedModeEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void switchOneHandedMode() {
|
||||||
|
if (DEBUG_INTERNAL_ACTION) {
|
||||||
|
Log.d(TAG, "switchOneHandedMode");
|
||||||
|
}
|
||||||
|
mSwitchActions.switchOneHandedMode();
|
||||||
|
}
|
||||||
|
|
||||||
public void onPressKey(final int code, final boolean isSinglePointer, final int autoCapsFlags,
|
public void onPressKey(final int code, final boolean isSinglePointer, final int autoCapsFlags,
|
||||||
final int recapitalizeMode) {
|
final int recapitalizeMode) {
|
||||||
if (DEBUG_EVENT) {
|
if (DEBUG_EVENT) {
|
||||||
|
@ -697,6 +716,12 @@ public final class KeyboardState {
|
||||||
}
|
}
|
||||||
} else if (code == Constants.CODE_ALPHA_FROM_CLIPBOARD) {
|
} else if (code == Constants.CODE_ALPHA_FROM_CLIPBOARD) {
|
||||||
setAlphabetKeyboard(autoCapsFlags, recapitalizeMode);
|
setAlphabetKeyboard(autoCapsFlags, recapitalizeMode);
|
||||||
|
} else if (code == Constants.CODE_START_ONE_HANDED_MODE) {
|
||||||
|
setOneHandedModeEnabled(true);
|
||||||
|
} else if (code == Constants.CODE_STOP_ONE_HANDED_MODE) {
|
||||||
|
setOneHandedModeEnabled(false);
|
||||||
|
} else if (code == Constants.CODE_SWITCH_ONE_HANDED_MODE) {
|
||||||
|
switchOneHandedMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -294,7 +294,7 @@ public final class MoreKeySpec {
|
||||||
// Append remained additional more keys to the tail of more keys.
|
// Append remained additional more keys to the tail of more keys.
|
||||||
out = CollectionUtils.arrayAsList(moreKeys, 0, moreKeysCount);
|
out = CollectionUtils.arrayAsList(moreKeys, 0, moreKeysCount);
|
||||||
for (int i = additionalIndex; i < additionalCount; i++) {
|
for (int i = additionalIndex; i < additionalCount; i++) {
|
||||||
out.add(additionalMoreKeys[additionalIndex]);
|
out.add(additionalMoreKeys[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (out == null && moreKeysCount > 0) {
|
if (out == null && moreKeysCount > 0) {
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
package org.dslul.openboard.inputmethod.latin
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.Gravity
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.ImageButton
|
||||||
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardActionListener
|
||||||
|
import org.dslul.openboard.inputmethod.latin.common.Constants
|
||||||
|
|
||||||
|
class KeyboardWrapperView @JvmOverloads constructor(
|
||||||
|
context: Context,
|
||||||
|
attrs: AttributeSet? = null,
|
||||||
|
defStyle: Int = 0
|
||||||
|
) : FrameLayout(context, attrs, defStyle), View.OnClickListener {
|
||||||
|
|
||||||
|
var keyboardActionListener: KeyboardActionListener? = null
|
||||||
|
|
||||||
|
private lateinit var stopOneHandedModeBtn: ImageButton
|
||||||
|
private lateinit var switchOneHandedModeBtn: ImageButton
|
||||||
|
private lateinit var keyboardView: View
|
||||||
|
private val iconStopOneHandedModeId: Int
|
||||||
|
private val iconSwitchOneHandedModeId: Int
|
||||||
|
|
||||||
|
var oneHandedModeEnabled = false
|
||||||
|
set(enabled) {
|
||||||
|
field = enabled
|
||||||
|
updateViewsVisibility()
|
||||||
|
requestLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
var oneHandedGravity = Gravity.NO_GRAVITY
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
updateSwitchButtonSide()
|
||||||
|
requestLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun onFinishInflate() {
|
||||||
|
super.onFinishInflate()
|
||||||
|
stopOneHandedModeBtn = findViewById(R.id.btn_stop_one_handed_mode)
|
||||||
|
stopOneHandedModeBtn.setImageResource(iconStopOneHandedModeId)
|
||||||
|
stopOneHandedModeBtn.visibility = GONE
|
||||||
|
switchOneHandedModeBtn = findViewById(R.id.btn_switch_one_handed_mode)
|
||||||
|
switchOneHandedModeBtn.setImageResource(iconSwitchOneHandedModeId)
|
||||||
|
switchOneHandedModeBtn.visibility = GONE
|
||||||
|
keyboardView = findViewById(R.id.keyboard_view)
|
||||||
|
|
||||||
|
stopOneHandedModeBtn.setOnClickListener(this)
|
||||||
|
switchOneHandedModeBtn.setOnClickListener(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RtlHardcoded")
|
||||||
|
fun switchOneHandedModeSide() {
|
||||||
|
oneHandedGravity = if (oneHandedGravity == Gravity.LEFT) Gravity.RIGHT else Gravity.LEFT
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateViewsVisibility() {
|
||||||
|
stopOneHandedModeBtn.visibility = if (oneHandedModeEnabled) VISIBLE else GONE
|
||||||
|
switchOneHandedModeBtn.visibility = if (oneHandedModeEnabled) VISIBLE else GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RtlHardcoded")
|
||||||
|
private fun updateSwitchButtonSide() {
|
||||||
|
switchOneHandedModeBtn.scaleX = if (oneHandedGravity == Gravity.LEFT) -1f else 1f
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(view: View) {
|
||||||
|
if (view === stopOneHandedModeBtn) {
|
||||||
|
keyboardActionListener?.onCodeInput(Constants.CODE_STOP_ONE_HANDED_MODE,
|
||||||
|
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE,
|
||||||
|
false /* isKeyRepeat */)
|
||||||
|
} else if (view === switchOneHandedModeBtn) {
|
||||||
|
keyboardActionListener?.onCodeInput(Constants.CODE_SWITCH_ONE_HANDED_MODE,
|
||||||
|
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE,
|
||||||
|
false /* isKeyRepeat */)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RtlHardcoded")
|
||||||
|
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
|
||||||
|
if (!oneHandedModeEnabled) {
|
||||||
|
super.onLayout(changed, left, top, right, bottom)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val isLeftGravity = oneHandedGravity == Gravity.LEFT
|
||||||
|
val width = right - left
|
||||||
|
val spareWidth = width - keyboardView.measuredWidth
|
||||||
|
|
||||||
|
val keyboardLeft = if (isLeftGravity) 0 else spareWidth
|
||||||
|
keyboardView.layout(
|
||||||
|
keyboardLeft,
|
||||||
|
0,
|
||||||
|
keyboardLeft + keyboardView.measuredWidth,
|
||||||
|
keyboardView.measuredHeight
|
||||||
|
)
|
||||||
|
|
||||||
|
val buttonsLeft = if (isLeftGravity) keyboardView.measuredWidth else 0
|
||||||
|
stopOneHandedModeBtn.layout(
|
||||||
|
buttonsLeft + (spareWidth - stopOneHandedModeBtn.measuredWidth) / 2,
|
||||||
|
stopOneHandedModeBtn.measuredHeight / 2,
|
||||||
|
buttonsLeft + (spareWidth + stopOneHandedModeBtn.measuredWidth) / 2,
|
||||||
|
3 * stopOneHandedModeBtn.measuredHeight / 2
|
||||||
|
)
|
||||||
|
switchOneHandedModeBtn.layout(
|
||||||
|
buttonsLeft + (spareWidth - switchOneHandedModeBtn.measuredWidth) / 2,
|
||||||
|
2 * stopOneHandedModeBtn.measuredHeight,
|
||||||
|
buttonsLeft + (spareWidth + switchOneHandedModeBtn.measuredWidth) / 2,
|
||||||
|
2 * stopOneHandedModeBtn.measuredHeight + switchOneHandedModeBtn.measuredHeight
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val keyboardAttr = context.obtainStyledAttributes(attrs,
|
||||||
|
R.styleable.Keyboard, defStyle, R.style.Keyboard)
|
||||||
|
iconStopOneHandedModeId = keyboardAttr.getResourceId(R.styleable.Keyboard_iconStopOneHandedMode, 0)
|
||||||
|
iconSwitchOneHandedModeId = keyboardAttr.getResourceId(R.styleable.Keyboard_iconSwitchOneHandedMode, 0)
|
||||||
|
keyboardAttr.recycle()
|
||||||
|
|
||||||
|
val themeAttr = context.obtainStyledAttributes(attrs,
|
||||||
|
R.styleable.KeyboardTheme, defStyle, 0)
|
||||||
|
val keyboardViewStyleId = themeAttr.getResourceId(R.styleable.KeyboardTheme_mainKeyboardViewStyle, 0)
|
||||||
|
themeAttr.recycle()
|
||||||
|
val styleAttr = context.obtainStyledAttributes(keyboardViewStyleId, intArrayOf(android.R.attr.background))
|
||||||
|
setBackgroundResource(styleAttr.getResourceId(0, 0))
|
||||||
|
styleAttr.recycle()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1341,11 +1341,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int getCurrentAutoCapsState() {
|
public int getCurrentAutoCapsState() {
|
||||||
return mInputLogic.getCurrentAutoCapsState(mSettings.getCurrent());
|
return mInputLogic.getCurrentAutoCapsState(mSettings.getCurrent());
|
||||||
}
|
}
|
||||||
|
|
||||||
int getCurrentRecapitalizeState() {
|
public int getCurrentRecapitalizeState() {
|
||||||
return mInputLogic.getCurrentRecapitalizeState();
|
return mInputLogic.getCurrentRecapitalizeState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -247,8 +247,11 @@ public final class Constants {
|
||||||
public static final int CODE_SYMBOL_SHIFT = -14;
|
public static final int CODE_SYMBOL_SHIFT = -14;
|
||||||
public static final int CODE_ALPHA_FROM_EMOJI = -15;
|
public static final int CODE_ALPHA_FROM_EMOJI = -15;
|
||||||
public static final int CODE_ALPHA_FROM_CLIPBOARD = -16;
|
public static final int CODE_ALPHA_FROM_CLIPBOARD = -16;
|
||||||
|
public static final int CODE_START_ONE_HANDED_MODE = -17;
|
||||||
|
public static final int CODE_STOP_ONE_HANDED_MODE = -18;
|
||||||
|
public static final int CODE_SWITCH_ONE_HANDED_MODE = -19;
|
||||||
// Code value representing the code is not specified.
|
// Code value representing the code is not specified.
|
||||||
public static final int CODE_UNSPECIFIED = -17;
|
public static final int CODE_UNSPECIFIED = -20;
|
||||||
|
|
||||||
public static boolean isLetterCode(final int code) {
|
public static boolean isLetterCode(final int code) {
|
||||||
return code >= CODE_SPACE;
|
return code >= CODE_SPACE;
|
||||||
|
@ -276,6 +279,9 @@ public final class Constants {
|
||||||
case CODE_TAB: return "tab";
|
case CODE_TAB: return "tab";
|
||||||
case CODE_ENTER: return "enter";
|
case CODE_ENTER: return "enter";
|
||||||
case CODE_SPACE: return "space";
|
case CODE_SPACE: return "space";
|
||||||
|
case CODE_START_ONE_HANDED_MODE: return "startOneHandedMode";
|
||||||
|
case CODE_STOP_ONE_HANDED_MODE: return "stopOneHandedMode";
|
||||||
|
case CODE_SWITCH_ONE_HANDED_MODE: return "switchOneHandedMode";
|
||||||
default:
|
default:
|
||||||
if (code < CODE_SPACE) return String.format("\\u%02X", code);
|
if (code < CODE_SPACE) return String.format("\\u%02X", code);
|
||||||
if (code < 0x100) return String.format("%c", code);
|
if (code < 0x100) return String.format("%c", code);
|
||||||
|
|
|
@ -717,6 +717,15 @@ public final class InputLogic {
|
||||||
// line, so that does affect the contents of the editor.
|
// line, so that does affect the contents of the editor.
|
||||||
inputTransaction.setDidAffectContents();
|
inputTransaction.setDidAffectContents();
|
||||||
break;
|
break;
|
||||||
|
case Constants.CODE_START_ONE_HANDED_MODE:
|
||||||
|
case Constants.CODE_STOP_ONE_HANDED_MODE:
|
||||||
|
// Note: One-handed mode activation is being
|
||||||
|
// handled in {@link KeyboardState#onEvent(Event,int)}.
|
||||||
|
break;
|
||||||
|
case Constants.CODE_SWITCH_ONE_HANDED_MODE:
|
||||||
|
// Note: Switching one-handed side is being
|
||||||
|
// handled in {@link KeyboardState#onEvent(Event,int)}.
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException("Unknown key code : " + event.getMKeyCode());
|
throw new RuntimeException("Unknown key code : " + event.getMKeyCode());
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package org.dslul.openboard.inputmethod.latin.settings;
|
package org.dslul.openboard.inputmethod.latin.settings;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
|
@ -24,6 +25,7 @@ import android.content.res.Resources;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import android.view.Gravity;
|
||||||
import org.dslul.openboard.inputmethod.latin.AudioAndHapticFeedbackManager;
|
import org.dslul.openboard.inputmethod.latin.AudioAndHapticFeedbackManager;
|
||||||
import org.dslul.openboard.inputmethod.latin.InputAttributes;
|
import org.dslul.openboard.inputmethod.latin.InputAttributes;
|
||||||
import org.dslul.openboard.inputmethod.latin.R;
|
import org.dslul.openboard.inputmethod.latin.R;
|
||||||
|
@ -107,6 +109,9 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
||||||
"pref_gesture_floating_preview_text";
|
"pref_gesture_floating_preview_text";
|
||||||
public static final String PREF_SHOW_SETUP_WIZARD_ICON = "pref_show_setup_wizard_icon";
|
public static final String PREF_SHOW_SETUP_WIZARD_ICON = "pref_show_setup_wizard_icon";
|
||||||
|
|
||||||
|
public static final String PREF_ONE_HANDED_MODE = "pref_one_handed_mode_enabled";
|
||||||
|
public static final String PREF_ONE_HANDED_GRAVITY = "pref_one_handed_mode_gravity";
|
||||||
|
|
||||||
public static final String PREF_KEY_IS_INTERNAL = "pref_key_is_internal";
|
public static final String PREF_KEY_IS_INTERNAL = "pref_key_is_internal";
|
||||||
|
|
||||||
public static final String PREF_ENABLE_METRICS_LOGGING = "pref_enable_metrics_logging";
|
public static final String PREF_ENABLE_METRICS_LOGGING = "pref_enable_metrics_logging";
|
||||||
|
@ -403,6 +408,23 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
||||||
return prefs.getBoolean(PREF_SHOW_SETUP_WIZARD_ICON, false);
|
return prefs.getBoolean(PREF_SHOW_SETUP_WIZARD_ICON, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean readOneHandedModeEnabled(final SharedPreferences prefs) {
|
||||||
|
return prefs.getBoolean(PREF_ONE_HANDED_MODE, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeOneHandedModeEnabled(final boolean enabled) {
|
||||||
|
mPrefs.edit().putBoolean(PREF_ONE_HANDED_MODE, enabled).apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RtlHardcoded")
|
||||||
|
public static int readOneHandedModeGravity(final SharedPreferences prefs) {
|
||||||
|
return prefs.getInt(PREF_ONE_HANDED_GRAVITY, Gravity.LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeOneHandedModeGravity(final int gravity) {
|
||||||
|
mPrefs.edit().putInt(PREF_ONE_HANDED_GRAVITY, gravity).apply();
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean readHasHardwareKeyboard(final Configuration conf) {
|
public static boolean readHasHardwareKeyboard(final Configuration conf) {
|
||||||
// The standard way of finding out whether we have a hardware keyboard. This code is taken
|
// The standard way of finding out whether we have a hardware keyboard. This code is taken
|
||||||
// from InputMethodService#onEvaluateInputShown, which canonically determines this.
|
// from InputMethodService#onEvaluateInputShown, which canonically determines this.
|
||||||
|
|
|
@ -82,6 +82,8 @@ public class SettingsValues {
|
||||||
public final boolean mDeleteSwipeEnabled;
|
public final boolean mDeleteSwipeEnabled;
|
||||||
public final boolean mClipboardHistoryEnabled;
|
public final boolean mClipboardHistoryEnabled;
|
||||||
public final long mClipboardHistoryRetentionTime;
|
public final long mClipboardHistoryRetentionTime;
|
||||||
|
public final boolean mOneHandedModeEnabled;
|
||||||
|
public final int mOneHandedModeGravity;
|
||||||
// Use bigrams to predict the next word when there is no input for it yet
|
// Use bigrams to predict the next word when there is no input for it yet
|
||||||
public final boolean mBigramPredictionEnabled;
|
public final boolean mBigramPredictionEnabled;
|
||||||
public final boolean mGestureInputEnabled;
|
public final boolean mGestureInputEnabled;
|
||||||
|
@ -237,6 +239,8 @@ public class SettingsValues {
|
||||||
mDeleteSwipeEnabled = Settings.readDeleteSwipeEnabled(prefs);
|
mDeleteSwipeEnabled = Settings.readDeleteSwipeEnabled(prefs);
|
||||||
mClipboardHistoryEnabled = Settings.readClipboardHistoryEnabled(prefs);
|
mClipboardHistoryEnabled = Settings.readClipboardHistoryEnabled(prefs);
|
||||||
mClipboardHistoryRetentionTime = Settings.readClipboardHistoryRetentionTime(prefs, res);
|
mClipboardHistoryRetentionTime = Settings.readClipboardHistoryRetentionTime(prefs, res);
|
||||||
|
mOneHandedModeEnabled = Settings.readOneHandedModeEnabled(prefs);
|
||||||
|
mOneHandedModeGravity = Settings.readOneHandedModeGravity(prefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMetricsLoggingEnabled() {
|
public boolean isMetricsLoggingEnabled() {
|
||||||
|
|
|
@ -182,6 +182,15 @@ public final class ResourceUtils {
|
||||||
return matchedAll;
|
return matchedAll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getKeyboardWidth(final Resources res, final SettingsValues settingsValues) {
|
||||||
|
final int defaultKeyboardWidth = getDefaultKeyboardWidth(res);
|
||||||
|
if (settingsValues.mOneHandedModeEnabled) {
|
||||||
|
return (int) res.getFraction(R.fraction.config_one_handed_mode_width,
|
||||||
|
defaultKeyboardWidth, defaultKeyboardWidth);
|
||||||
|
}
|
||||||
|
return defaultKeyboardWidth;
|
||||||
|
}
|
||||||
|
|
||||||
public static int getDefaultKeyboardWidth(final Resources res) {
|
public static int getDefaultKeyboardWidth(final Resources res) {
|
||||||
final DisplayMetrics dm = res.getDisplayMetrics();
|
final DisplayMetrics dm = res.getDisplayMetrics();
|
||||||
return dm.widthPixels;
|
return dm.widthPixels;
|
||||||
|
|
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 808 B |
After Width: | Height: | Size: 929 B |
After Width: | Height: | Size: 832 B |
After Width: | Height: | Size: 648 B |
After Width: | Height: | Size: 765 B |
After Width: | Height: | Size: 374 B |
After Width: | Height: | Size: 371 B |
After Width: | Height: | Size: 351 B |
After Width: | Height: | Size: 730 B |
After Width: | Height: | Size: 491 B |
After Width: | Height: | Size: 247 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 773 B |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 951 B |
After Width: | Height: | Size: 314 B |
After Width: | Height: | Size: 372 B |
After Width: | Height: | Size: 391 B |
After Width: | Height: | Size: 2 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 527 B |
After Width: | Height: | Size: 560 B |
After Width: | Height: | Size: 617 B |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 468 B |
After Width: | Height: | Size: 539 B |
After Width: | Height: | Size: 641 B |
|
@ -37,9 +37,34 @@
|
||||||
|
|
||||||
<!-- To ensure that key preview popup is correctly placed when the current system locale is
|
<!-- To ensure that key preview popup is correctly placed when the current system locale is
|
||||||
one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
|
one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
|
||||||
<org.dslul.openboard.inputmethod.keyboard.MainKeyboardView
|
<org.dslul.openboard.inputmethod.latin.KeyboardWrapperView
|
||||||
android:id="@+id/keyboard_view"
|
android:id="@+id/keyboard_view_wrapper"
|
||||||
android:layoutDirection="ltr"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content"
|
||||||
|
android:layoutDirection="ltr" >
|
||||||
|
|
||||||
|
<org.dslul.openboard.inputmethod.keyboard.MainKeyboardView
|
||||||
|
android:id="@+id/keyboard_view"
|
||||||
|
android:layoutDirection="ltr"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/btn_stop_one_handed_mode"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
style="?attr/suggestionWordStyle" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/btn_switch_one_handed_mode"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
style="?attr/suggestionWordStyle" />
|
||||||
|
|
||||||
|
</org.dslul.openboard.inputmethod.latin.KeyboardWrapperView>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -56,7 +56,6 @@
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/suggestions_strip_clipboard_key"
|
android:id="@+id/suggestions_strip_clipboard_key"
|
||||||
android:layout_width="@dimen/config_suggestions_strip_edge_key_width"
|
android:layout_width="@dimen/config_suggestions_strip_edge_key_width"
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
style="?attr/suggestionWordStyle" />
|
style="?attr/suggestionWordStyle" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
<resources>
|
<resources>
|
||||||
<dimen name="config_key_hysteresis_distance">40.0dp</dimen>
|
<dimen name="config_key_hysteresis_distance">40.0dp</dimen>
|
||||||
|
|
||||||
|
<!-- Amount of width reduction in one-handed mode -->
|
||||||
|
<fraction name="config_one_handed_mode_width">76%</fraction>
|
||||||
|
|
||||||
<!-- Preferable keyboard height in absolute scale: 48.0mm -->
|
<!-- Preferable keyboard height in absolute scale: 48.0mm -->
|
||||||
<!-- This config_default_keyboard_height value should match with keyboard-heights.xml -->
|
<!-- This config_default_keyboard_height value should match with keyboard-heights.xml -->
|
||||||
<dimen name="config_default_keyboard_height">302.4dp</dimen>
|
<dimen name="config_default_keyboard_height">302.4dp</dimen>
|
||||||
|
|
|
@ -290,6 +290,9 @@
|
||||||
<attr name="iconClipboardActionKey" format="reference" />
|
<attr name="iconClipboardActionKey" format="reference" />
|
||||||
<attr name="iconClipboardNormalKey" format="reference" />
|
<attr name="iconClipboardNormalKey" format="reference" />
|
||||||
<attr name="iconClearClipboardKey" format="reference" />
|
<attr name="iconClearClipboardKey" format="reference" />
|
||||||
|
<attr name="iconStartOneHandedMode" format="reference" />
|
||||||
|
<attr name="iconStopOneHandedMode" format="reference" />
|
||||||
|
<attr name="iconSwitchOneHandedMode" format="reference" />
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
<declare-styleable name="Keyboard_GridRows">
|
<declare-styleable name="Keyboard_GridRows">
|
||||||
|
@ -512,6 +515,7 @@
|
||||||
<attr name="hasShortcutKey" format="boolean" />
|
<attr name="hasShortcutKey" format="boolean" />
|
||||||
<attr name="languageSwitchKeyEnabled" format="boolean" />
|
<attr name="languageSwitchKeyEnabled" format="boolean" />
|
||||||
<attr name="emojiKeyEnabled" format="boolean" />
|
<attr name="emojiKeyEnabled" format="boolean" />
|
||||||
|
<attr name="oneHandedModeEnabled" format="boolean" />
|
||||||
<attr name="numberRowEnabled" format="boolean" />
|
<attr name="numberRowEnabled" format="boolean" />
|
||||||
<attr name="isMultiLine" format="boolean" />
|
<attr name="isMultiLine" format="boolean" />
|
||||||
<attr name="imeAction" format="enum">
|
<attr name="imeAction" format="enum">
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
look at input history to suggest a hopefully helpful suggestions for the next word? -->
|
look at input history to suggest a hopefully helpful suggestions for the next word? -->
|
||||||
<bool name="config_default_next_word_prediction">true</bool>
|
<bool name="config_default_next_word_prediction">true</bool>
|
||||||
|
|
||||||
|
<!-- Maximum time for a clipboard history entry to be kept, in minutes. -->
|
||||||
|
<integer name="config_clipboard_history_retention_time">10</integer>
|
||||||
|
|
||||||
<integer name="config_delay_in_milliseconds_to_update_shift_state">100</integer>
|
<integer name="config_delay_in_milliseconds_to_update_shift_state">100</integer>
|
||||||
<integer name="config_double_space_period_timeout">1100</integer>
|
<integer name="config_double_space_period_timeout">1100</integer>
|
||||||
|
|
||||||
|
|
|
@ -22,11 +22,11 @@
|
||||||
<resources>
|
<resources>
|
||||||
<bool name="config_use_fullscreen_mode">false</bool>
|
<bool name="config_use_fullscreen_mode">false</bool>
|
||||||
|
|
||||||
<!-- Maximum time for a clipboard history entry to be kept, in minutes. -->
|
|
||||||
<integer name="config_clipboard_history_retention_time">10</integer>
|
|
||||||
|
|
||||||
<dimen name="config_key_hysteresis_distance">8.0dp</dimen>
|
<dimen name="config_key_hysteresis_distance">8.0dp</dimen>
|
||||||
|
|
||||||
|
<!-- Amount of width reduction in one-handed mode -->
|
||||||
|
<fraction name="config_one_handed_mode_width">86%</fraction>
|
||||||
|
|
||||||
<!-- Preferable keyboard height in absolute scale: 1.285in -->
|
<!-- Preferable keyboard height in absolute scale: 1.285in -->
|
||||||
<!-- This config_default_keyboard_height value should match with keyboard-heights.xml -->
|
<!-- This config_default_keyboard_height value should match with keyboard-heights.xml -->
|
||||||
<dimen name="config_default_keyboard_height">205.6dp</dimen>
|
<dimen name="config_default_keyboard_height">205.6dp</dimen>
|
||||||
|
|
|
@ -41,5 +41,8 @@
|
||||||
<item name="iconClipboardActionKey">@drawable/sym_keyboard_clipboard_holo_dark</item>
|
<item name="iconClipboardActionKey">@drawable/sym_keyboard_clipboard_holo_dark</item>
|
||||||
<item name="iconClipboardNormalKey">@drawable/sym_keyboard_clipboard_holo_dark</item>
|
<item name="iconClipboardNormalKey">@drawable/sym_keyboard_clipboard_holo_dark</item>
|
||||||
<item name="iconClearClipboardKey">@drawable/sym_keyboard_clear_clipboard_holo_dark</item>
|
<item name="iconClearClipboardKey">@drawable/sym_keyboard_clear_clipboard_holo_dark</item>
|
||||||
|
<item name="iconStartOneHandedMode">@drawable/sym_keyboard_start_onehanded_holo_dark</item>
|
||||||
|
<item name="iconStopOneHandedMode">@drawable/sym_keyboard_stop_onehanded_holo_dark</item>
|
||||||
|
<item name="iconSwitchOneHandedMode">@drawable/sym_keyboard_switch_onehanded_holo_dark</item>
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -46,5 +46,8 @@
|
||||||
<item name="iconClipboardActionKey">@drawable/sym_keyboard_clipboard_lxx_dark</item>
|
<item name="iconClipboardActionKey">@drawable/sym_keyboard_clipboard_lxx_dark</item>
|
||||||
<item name="iconClipboardNormalKey">@drawable/sym_keyboard_clipboard_lxx_dark</item>
|
<item name="iconClipboardNormalKey">@drawable/sym_keyboard_clipboard_lxx_dark</item>
|
||||||
<item name="iconClearClipboardKey">@drawable/sym_keyboard_clear_clipboard_lxx_dark</item>
|
<item name="iconClearClipboardKey">@drawable/sym_keyboard_clear_clipboard_lxx_dark</item>
|
||||||
|
<item name="iconStartOneHandedMode">@drawable/sym_keyboard_start_onehanded_lxx_dark</item>
|
||||||
|
<item name="iconStopOneHandedMode">@drawable/sym_keyboard_stop_onehanded_lxx_dark</item>
|
||||||
|
<item name="iconSwitchOneHandedMode">@drawable/sym_keyboard_switch_onehanded_lxx_dark</item>
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -46,5 +46,8 @@
|
||||||
<item name="iconClipboardActionKey">@drawable/sym_keyboard_clipboard_lxx_dark</item>
|
<item name="iconClipboardActionKey">@drawable/sym_keyboard_clipboard_lxx_dark</item>
|
||||||
<item name="iconClipboardNormalKey">@drawable/sym_keyboard_clipboard_lxx_light</item>
|
<item name="iconClipboardNormalKey">@drawable/sym_keyboard_clipboard_lxx_light</item>
|
||||||
<item name="iconClearClipboardKey">@drawable/sym_keyboard_clear_clipboard_lxx_light</item>
|
<item name="iconClearClipboardKey">@drawable/sym_keyboard_clear_clipboard_lxx_light</item>
|
||||||
|
<item name="iconStartOneHandedMode">@drawable/sym_keyboard_start_onehanded_lxx_light</item>
|
||||||
|
<item name="iconStopOneHandedMode">@drawable/sym_keyboard_stop_onehanded_lxx_light</item>
|
||||||
|
<item name="iconSwitchOneHandedMode">@drawable/sym_keyboard_switch_onehanded_lxx_light</item>
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -100,7 +100,7 @@
|
||||||
latin:backgroundType="functional" />
|
latin:backgroundType="functional" />
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="languageSwitchKeyStyle"
|
latin:styleName="languageSwitchKeyStyle"
|
||||||
latin:keySpec="!icon/language_switch_key|!code/key_language_switch"
|
latin:keySpec="!text/keyspec_language_switch"
|
||||||
latin:keyActionFlags="noKeyPreview|altCodeWhileTyping|enableLongPress"
|
latin:keyActionFlags="noKeyPreview|altCodeWhileTyping|enableLongPress"
|
||||||
latin:altCode="!code/key_space"
|
latin:altCode="!code/key_space"
|
||||||
latin:backgroundType="functional" />
|
latin:backgroundType="functional" />
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
<default>
|
<default>
|
||||||
<Key
|
<Key
|
||||||
latin:keyStyle="emojiKeyStyle"
|
latin:keyStyle="emojiKeyStyle"
|
||||||
latin:backgroundType="action"
|
|
||||||
latin:keyWidth="fillRight" />
|
latin:keyWidth="fillRight" />
|
||||||
</default>
|
</default>
|
||||||
</switch>
|
</switch>
|
||||||
|
|
|
@ -126,7 +126,7 @@
|
||||||
latin:backgroundType="functional" />
|
latin:backgroundType="functional" />
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="languageSwitchKeyStyle"
|
latin:styleName="languageSwitchKeyStyle"
|
||||||
latin:keySpec="!icon/language_switch_key|!code/key_language_switch"
|
latin:keySpec="!text/keyspec_language_switch"
|
||||||
latin:keyActionFlags="noKeyPreview|altCodeWhileTyping|enableLongPress"
|
latin:keyActionFlags="noKeyPreview|altCodeWhileTyping|enableLongPress"
|
||||||
latin:altCode="!code/key_space"
|
latin:altCode="!code/key_space"
|
||||||
latin:backgroundType="functional" />
|
latin:backgroundType="functional" />
|
||||||
|
|
|
@ -20,52 +20,92 @@
|
||||||
|
|
||||||
<merge
|
<merge
|
||||||
xmlns:latin="http://schemas.android.com/apk/res-auto"
|
xmlns:latin="http://schemas.android.com/apk/res-auto"
|
||||||
>
|
>
|
||||||
<!-- Key style for the key which may have settings key as more keys. -->
|
<!-- Key style for the key which may have settings key as more keys. -->
|
||||||
<switch>
|
<switch>
|
||||||
<case
|
<case
|
||||||
latin:clobberSettingsKey="true"
|
latin:clobberSettingsKey="true"
|
||||||
>
|
>
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="settingsMoreKeysStyle"
|
latin:styleName="settingsMoreKeysStyle"
|
||||||
latin:backgroundType="functional" />
|
latin:backgroundType="functional"/>
|
||||||
</case>
|
</case>
|
||||||
<case
|
<case
|
||||||
latin:emojiKeyEnabled="true"
|
latin:oneHandedModeEnabled="true"
|
||||||
latin:languageSwitchKeyEnabled="true"
|
latin:languageSwitchKeyEnabled="true"
|
||||||
>
|
latin:emojiKeyEnabled="true">
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="settingsMoreKeysStyle"
|
latin:styleName="settingsMoreKeysStyle"
|
||||||
latin:keyLabelFlags="hasPopupHint"
|
latin:keyLabelFlags="hasPopupHint"
|
||||||
latin:additionalMoreKeys="!text/keyspec_settings,!text/keyspec_clipboard_normal_key"
|
latin:backgroundType="functional"
|
||||||
latin:backgroundType="functional" />
|
latin:additionalMoreKeys="!text/keyspec_settings,!text/keyspec_clipboard_normal_key"/>
|
||||||
</case>
|
</case>
|
||||||
<case
|
<case
|
||||||
latin:emojiKeyEnabled="false"
|
latin:oneHandedModeEnabled="true"
|
||||||
latin:languageSwitchKeyEnabled="true"
|
latin:languageSwitchKeyEnabled="true"
|
||||||
>
|
latin:emojiKeyEnabled="false">
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="settingsMoreKeysStyle"
|
latin:styleName="settingsMoreKeysStyle"
|
||||||
latin:keyLabelFlags="hasPopupHint"
|
latin:keyLabelFlags="hasPopupHint"
|
||||||
latin:additionalMoreKeys="!text/keyspec_settings,!text/keyspec_clipboard_normal_key,!text/keyspec_emoji_normal_key"
|
latin:backgroundType="functional"
|
||||||
latin:backgroundType="functional" />
|
latin:additionalMoreKeys="!text/keyspec_settings,!text/keyspec_clipboard_normal_key,!text/keyspec_emoji_normal_key"/>
|
||||||
</case>
|
</case>
|
||||||
<case
|
<case
|
||||||
latin:emojiKeyEnabled="true"
|
latin:oneHandedModeEnabled="true"
|
||||||
latin:languageSwitchKeyEnabled="false"
|
latin:languageSwitchKeyEnabled="false"
|
||||||
>
|
latin:emojiKeyEnabled="true">
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="settingsMoreKeysStyle"
|
latin:styleName="settingsMoreKeysStyle"
|
||||||
latin:keyLabelFlags="hasPopupHint"
|
latin:keyLabelFlags="hasPopupHint"
|
||||||
latin:additionalMoreKeys="!text/keyspec_settings,!icon/language_switch_key|!code/key_language_switch,!text/keyspec_clipboard_normal_key"
|
latin:backgroundType="functional"
|
||||||
latin:backgroundType="functional" />
|
latin:additionalMoreKeys="!text/keyspec_settings,!text/keyspec_clipboard_normal_key,!text/keyspec_language_switch"/>
|
||||||
|
</case>
|
||||||
|
<case
|
||||||
|
latin:oneHandedModeEnabled="true"
|
||||||
|
latin:languageSwitchKeyEnabled="false"
|
||||||
|
latin:emojiKeyEnabled="false">
|
||||||
|
<key-style
|
||||||
|
latin:styleName="settingsMoreKeysStyle"
|
||||||
|
latin:keyLabelFlags="hasPopupHint"
|
||||||
|
latin:backgroundType="functional"
|
||||||
|
latin:additionalMoreKeys="!text/keyspec_settings,!text/keyspec_clipboard_normal_key,!text/keyspec_language_switch,!text/keyspec_emoji_normal_key"/>
|
||||||
|
</case>
|
||||||
|
<case
|
||||||
|
latin:oneHandedModeEnabled="false"
|
||||||
|
latin:languageSwitchKeyEnabled="true"
|
||||||
|
latin:emojiKeyEnabled="true">
|
||||||
|
<key-style
|
||||||
|
latin:styleName="settingsMoreKeysStyle"
|
||||||
|
latin:keyLabelFlags="hasPopupHint"
|
||||||
|
latin:backgroundType="functional"
|
||||||
|
latin:additionalMoreKeys="!text/keyspec_settings,!text/keyspec_clipboard_normal_key,!text/keyspec_start_onehanded_mode"/>
|
||||||
|
</case>
|
||||||
|
<case
|
||||||
|
latin:oneHandedModeEnabled="false"
|
||||||
|
latin:languageSwitchKeyEnabled="true"
|
||||||
|
latin:emojiKeyEnabled="false">
|
||||||
|
<key-style
|
||||||
|
latin:styleName="settingsMoreKeysStyle"
|
||||||
|
latin:keyLabelFlags="hasPopupHint"
|
||||||
|
latin:backgroundType="functional"
|
||||||
|
latin:additionalMoreKeys="!text/keyspec_settings,!text/keyspec_clipboard_normal_key,!text/keyspec_start_onehanded_mode,!text/keyspec_emoji_normal_key"/>
|
||||||
|
</case>
|
||||||
|
<case
|
||||||
|
latin:oneHandedModeEnabled="false"
|
||||||
|
latin:languageSwitchKeyEnabled="false"
|
||||||
|
latin:emojiKeyEnabled="true">
|
||||||
|
<key-style
|
||||||
|
latin:styleName="settingsMoreKeysStyle"
|
||||||
|
latin:keyLabelFlags="hasPopupHint"
|
||||||
|
latin:backgroundType="functional"
|
||||||
|
latin:additionalMoreKeys="!text/keyspec_settings,!text/keyspec_clipboard_normal_key,!text/keyspec_start_onehanded_mode,!text/keyspec_language_switch"/>
|
||||||
</case>
|
</case>
|
||||||
<default>
|
<default>
|
||||||
<key-style
|
<key-style
|
||||||
latin:styleName="settingsMoreKeysStyle"
|
latin:styleName="settingsMoreKeysStyle"
|
||||||
latin:keyLabelFlags="hasPopupHint"
|
latin:keyLabelFlags="hasPopupHint"
|
||||||
latin:additionalMoreKeys="!text/keyspec_settings,!icon/language_switch_key|!code/key_language_switch,!text/keyspec_clipboard_normal_key,!text/keyspec_emoji_normal_key"
|
latin:backgroundType="functional"
|
||||||
latin:backgroundType="functional" />
|
latin:additionalMoreKeys="!text/keyspec_settings,!text/keyspec_clipboard_normal_key,!text/keyspec_start_onehanded_mode,!text/keyspec_language_switch,!text/keyspec_emoji_normal_key"/>
|
||||||
</default>
|
</default>
|
||||||
</switch>
|
</switch>
|
||||||
</merge>
|
</merge>
|
||||||
|
|
|
@ -262,6 +262,8 @@
|
||||||
<string name="keyspec_emoji_normal_key">!icon/emoji_normal_key|!code/key_emoji</string>
|
<string name="keyspec_emoji_normal_key">!icon/emoji_normal_key|!code/key_emoji</string>
|
||||||
<string name="keyspec_clipboard_action_key">!icon/clipboard_action_key|!code/key_clipboard</string>
|
<string name="keyspec_clipboard_action_key">!icon/clipboard_action_key|!code/key_clipboard</string>
|
||||||
<string name="keyspec_clipboard_normal_key">!icon/clipboard_normal_key|!code/key_clipboard</string>
|
<string name="keyspec_clipboard_normal_key">!icon/clipboard_normal_key|!code/key_clipboard</string>
|
||||||
|
<string name="keyspec_start_onehanded_mode">!icon/start_onehanded_mode_key|!code/key_start_onehanded</string>
|
||||||
|
<string name="keyspec_language_switch">!icon/language_switch_key|!code/key_language_switch</string>
|
||||||
<string name="label_go_key">!string/label_go_key</string>
|
<string name="label_go_key">!string/label_go_key</string>
|
||||||
<string name="label_send_key">!string/label_send_key</string>
|
<string name="label_send_key">!string/label_send_key</string>
|
||||||
<string name="label_next_key">!string/label_next_key</string>
|
<string name="label_next_key">!string/label_next_key</string>
|
||||||
|
|