switch internal codes for functional keys to the same as florisboard

for better compatibility of layouts
also convert labels
This commit is contained in:
Helium314 2024-03-02 21:02:48 +01:00
parent 7b0ee924ae
commit a34b3f4cdd
40 changed files with 448 additions and 410 deletions

View file

@ -14,6 +14,7 @@ import android.view.inputmethod.EditorInfo
import helium314.keyboard.keyboard.Key import helium314.keyboard.keyboard.Key
import helium314.keyboard.keyboard.Keyboard import helium314.keyboard.keyboard.Keyboard
import helium314.keyboard.keyboard.KeyboardId import helium314.keyboard.keyboard.KeyboardId
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
import helium314.keyboard.latin.R import helium314.keyboard.latin.R
import helium314.keyboard.latin.common.Constants import helium314.keyboard.latin.common.Constants
import helium314.keyboard.latin.common.StringUtils import helium314.keyboard.latin.common.StringUtils
@ -23,17 +24,17 @@ internal class KeyCodeDescriptionMapper private constructor() {
private val mKeyCodeMap = SparseIntArray().apply { private val mKeyCodeMap = SparseIntArray().apply {
// Special non-character codes defined in Keyboard // Special non-character codes defined in Keyboard
put(Constants.CODE_SPACE, R.string.spoken_description_space) put(Constants.CODE_SPACE, R.string.spoken_description_space)
put(Constants.CODE_DELETE, R.string.spoken_description_delete) put(KeyCode.DELETE, R.string.spoken_description_delete)
put(Constants.CODE_ENTER, R.string.spoken_description_return) put(Constants.CODE_ENTER, R.string.spoken_description_return)
put(Constants.CODE_SETTINGS, R.string.spoken_description_settings) put(KeyCode.SETTINGS, R.string.spoken_description_settings)
put(Constants.CODE_SHIFT, R.string.spoken_description_shift) put(KeyCode.SHIFT, R.string.spoken_description_shift)
put(Constants.CODE_SHORTCUT, R.string.spoken_description_mic) put(KeyCode.VOICE_INPUT, R.string.spoken_description_mic)
put(Constants.CODE_SWITCH_ALPHA_SYMBOL, R.string.spoken_description_to_symbol) put(KeyCode.ALPHA_SYMBOL, R.string.spoken_description_to_symbol)
put(Constants.CODE_TAB, R.string.spoken_description_tab) put(Constants.CODE_TAB, R.string.spoken_description_tab)
put(Constants.CODE_LANGUAGE_SWITCH, R.string.spoken_description_language_switch) put(KeyCode.LANGUAGE_SWITCH, R.string.spoken_description_language_switch)
put(Constants.CODE_ACTION_NEXT, R.string.spoken_description_action_next) put(KeyCode.ACTION_NEXT, R.string.spoken_description_action_next)
put(Constants.CODE_ACTION_PREVIOUS, R.string.spoken_description_action_previous) put(KeyCode.ACTION_PREVIOUS, R.string.spoken_description_action_previous)
put(Constants.CODE_EMOJI, R.string.spoken_description_emoji) put(KeyCode.EMOJI, R.string.spoken_description_emoji)
// Because the upper-case and lower-case mappings of the following letters is depending on // Because the upper-case and lower-case mappings of the following letters is depending on
// the locale, the upper case descriptions should be defined here. The lower case // the locale, the upper case descriptions should be defined here. The lower case
// descriptions are handled in {@link #getSpokenLetterDescriptionId(Context,int)}. // descriptions are handled in {@link #getSpokenLetterDescriptionId(Context,int)}.
@ -57,13 +58,13 @@ internal class KeyCodeDescriptionMapper private constructor() {
*/ */
fun getDescriptionForKey(context: Context, keyboard: Keyboard?, key: Key, shouldObscure: Boolean): String? { fun getDescriptionForKey(context: Context, keyboard: Keyboard?, key: Key, shouldObscure: Boolean): String? {
val code = key.code val code = key.code
if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL || code == Constants.CODE_SWITCH_SYMBOL || code == Constants.CODE_SWITCH_ALPHA) { if (code == KeyCode.ALPHA_SYMBOL || code == KeyCode.SYMBOL || code == KeyCode.ALPHA) {
val description = getDescriptionForSwitchAlphaSymbol(context, keyboard) val description = getDescriptionForSwitchAlphaSymbol(context, keyboard)
if (description != null) { if (description != null) {
return description return description
} }
} }
if (code == Constants.CODE_SHIFT) { if (code == KeyCode.SHIFT) {
return getDescriptionForShiftKey(context, keyboard) return getDescriptionForShiftKey(context, keyboard)
} }
if (code == Constants.CODE_ENTER) { if (code == Constants.CODE_ENTER) {
@ -71,11 +72,11 @@ internal class KeyCodeDescriptionMapper private constructor() {
// regular enter cases, taking care of all modes. // regular enter cases, taking care of all modes.
return getDescriptionForActionKey(context, keyboard, key) return getDescriptionForActionKey(context, keyboard, key)
} }
if (code == Constants.CODE_OUTPUT_TEXT) { if (code == KeyCode.MULTIPLE_CODE_POINTS) {
return key.outputText ?: context.getString(R.string.spoken_description_unknown) return key.outputText ?: context.getString(R.string.spoken_description_unknown)
} }
// Just attempt to speak the description. // Just attempt to speak the description.
if (code != Constants.CODE_UNSPECIFIED) { if (code != KeyCode.NOT_SPECIFIED) {
// If the key description should be obscured, now is the time to do it. // If the key description should be obscured, now is the time to do it.
val isDefinedNonCtrl = (Character.isDefined(code) val isDefinedNonCtrl = (Character.isDefined(code)
&& !Character.isISOControl(code)) && !Character.isISOControl(code))

View file

@ -8,6 +8,7 @@ package helium314.keyboard.event
import android.text.SpannableStringBuilder import android.text.SpannableStringBuilder
import android.text.TextUtils import android.text.TextUtils
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
import helium314.keyboard.latin.common.Constants import helium314.keyboard.latin.common.Constants
import java.util.* import java.util.*
@ -104,7 +105,7 @@ class CombinerChain(initialText: String) {
*/ */
fun applyProcessedEvent(event: Event?) { fun applyProcessedEvent(event: Event?) {
if (null != event) { // TODO: figure out the generic way of doing this if (null != event) { // TODO: figure out the generic way of doing this
if (Constants.CODE_DELETE == event.mKeyCode) { if (KeyCode.DELETE == event.mKeyCode) {
val length = mCombinedText.length val length = mCombinedText.length
if (length > 0) { if (length > 0) {
val lastCodePoint = mCombinedText.codePointBefore(length) val lastCodePoint = mCombinedText.codePointBefore(length)

View file

@ -8,6 +8,7 @@ package helium314.keyboard.event
import android.text.TextUtils import android.text.TextUtils
import android.util.SparseIntArray import android.util.SparseIntArray
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
import helium314.keyboard.latin.common.Constants import helium314.keyboard.latin.common.Constants
import java.text.Normalizer import java.text.Normalizer
import java.util.* import java.util.*
@ -211,7 +212,7 @@ class DeadKeyCombiner : Combiner {
return resultEvent return resultEvent
} }
if (event.isFunctionalKeyEvent) { if (event.isFunctionalKeyEvent) {
if (Constants.CODE_DELETE == event.mKeyCode) { // Remove the last code point if (KeyCode.DELETE == event.mKeyCode) { // Remove the last code point
val trimIndex = mDeadSequence.length - Character.charCount( val trimIndex = mDeadSequence.length - Character.charCount(
mDeadSequence.codePointBefore(mDeadSequence.length)) mDeadSequence.codePointBefore(mDeadSequence.length))
mDeadSequence.setLength(trimIndex) mDeadSequence.setLength(trimIndex)

View file

@ -2,6 +2,7 @@
package helium314.keyboard.event package helium314.keyboard.event
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
import helium314.keyboard.latin.common.Constants import helium314.keyboard.latin.common.Constants
import java.lang.StringBuilder import java.lang.StringBuilder
import java.util.ArrayList import java.util.ArrayList
@ -14,13 +15,13 @@ class HangulCombiner : Combiner {
private val syllable: HangulSyllable? get() = history.lastOrNull() private val syllable: HangulSyllable? get() = history.lastOrNull()
override fun processEvent(previousEvents: ArrayList<Event>?, event: Event): Event { override fun processEvent(previousEvents: ArrayList<Event>?, event: Event): Event {
if (event.mKeyCode == Constants.CODE_SHIFT) return event if (event.mKeyCode == KeyCode.SHIFT) return event
if (Character.isWhitespace(event.mCodePoint)) { if (Character.isWhitespace(event.mCodePoint)) {
val text = combiningStateFeedback val text = combiningStateFeedback
reset() reset()
return createEventChainFromSequence(text, event) return createEventChainFromSequence(text, event)
} else if (event.isFunctionalKeyEvent) { } else if (event.isFunctionalKeyEvent) {
if(event.mKeyCode == Constants.CODE_DELETE) { if(event.mKeyCode == KeyCode.DELETE) {
return when { return when {
history.size == 1 && composingWord.isEmpty() || history.isEmpty() && composingWord.length == 1 -> { history.size == 1 && composingWord.isEmpty() || history.isEmpty() && composingWord.length == 1 -> {
reset() reset()
@ -327,7 +328,7 @@ class HangulCombiner : Combiner {
0x11ba to 0x11ba to 0x11bb // ㅆ 0x11ba to 0x11ba to 0x11bb // ㅆ
) )
private fun createEventChainFromSequence(text: CharSequence, originalEvent: Event): Event { private fun createEventChainFromSequence(text: CharSequence, originalEvent: Event): Event {
return Event.createSoftwareTextEvent(text, Constants.CODE_OUTPUT_TEXT, originalEvent) return Event.createSoftwareTextEvent(text, KeyCode.MULTIPLE_CODE_POINTS, originalEvent)
} }
} }

View file

@ -8,6 +8,7 @@ package helium314.keyboard.event
import android.view.KeyCharacterMap import android.view.KeyCharacterMap
import android.view.KeyEvent import android.view.KeyEvent
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
import helium314.keyboard.latin.common.Constants import helium314.keyboard.latin.common.Constants
/** /**
@ -30,7 +31,7 @@ class HardwareKeyboardEventDecoder(val mDeviceId: Int) : HardwareEventDecoder {
val keyCode = keyEvent.keyCode val keyCode = keyEvent.keyCode
val isKeyRepeat = 0 != keyEvent.repeatCount val isKeyRepeat = 0 != keyEvent.repeatCount
if (KeyEvent.KEYCODE_DEL == keyCode) { if (KeyEvent.KEYCODE_DEL == keyCode) {
return Event.createHardwareKeypressEvent(Event.NOT_A_CODE_POINT, Constants.CODE_DELETE, null /* next */, isKeyRepeat) return Event.createHardwareKeypressEvent(Event.NOT_A_CODE_POINT, KeyCode.DELETE, null /* next */, isKeyRepeat)
} }
if (keyEvent.isPrintingKey || KeyEvent.KEYCODE_SPACE == keyCode || KeyEvent.KEYCODE_ENTER == keyCode) { if (keyEvent.isPrintingKey || KeyEvent.KEYCODE_SPACE == keyCode || KeyEvent.KEYCODE_ENTER == keyCode) {
if (0 != codePointAndFlags and KeyCharacterMap.COMBINING_ACCENT) { // A dead key. if (0 != codePointAndFlags and KeyCharacterMap.COMBINING_ACCENT) { // A dead key.
@ -44,7 +45,7 @@ class HardwareKeyboardEventDecoder(val mDeviceId: Int) : HardwareEventDecoder {
// Latin IME decide what to do with it. // Latin IME decide what to do with it.
if (keyEvent.isShiftPressed) { if (keyEvent.isShiftPressed) {
Event.createHardwareKeypressEvent(Event.NOT_A_CODE_POINT, Event.createHardwareKeypressEvent(Event.NOT_A_CODE_POINT,
Constants.CODE_SHIFT_ENTER, null /* next */, isKeyRepeat) KeyCode.SHIFT_ENTER, null /* next */, isKeyRepeat)
} else Event.createHardwareKeypressEvent(Constants.CODE_ENTER, keyCode, } else Event.createHardwareKeypressEvent(Constants.CODE_ENTER, keyCode,
null /* next */, isKeyRepeat) null /* next */, isKeyRepeat)
} else Event.createHardwareKeypressEvent(codePointAndFlags, keyCode, null /* next */, isKeyRepeat) } else Event.createHardwareKeypressEvent(codePointAndFlags, keyCode, null /* next */, isKeyRepeat)

View file

@ -17,6 +17,7 @@ import helium314.keyboard.keyboard.internal.KeyVisualAttributes;
import helium314.keyboard.keyboard.internal.KeyboardIconsSet; import helium314.keyboard.keyboard.internal.KeyboardIconsSet;
import helium314.keyboard.keyboard.internal.KeyboardParams; import helium314.keyboard.keyboard.internal.KeyboardParams;
import helium314.keyboard.keyboard.internal.PopupKeySpec; import helium314.keyboard.keyboard.internal.PopupKeySpec;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.PopupSet; import helium314.keyboard.keyboard.internal.keyboard_parser.floris.PopupSet;
import helium314.keyboard.latin.common.Constants; import helium314.keyboard.latin.common.Constants;
import helium314.keyboard.latin.common.StringUtils; import helium314.keyboard.latin.common.StringUtils;
@ -26,12 +27,6 @@ import java.util.Arrays;
import java.util.Locale; import java.util.Locale;
import static helium314.keyboard.keyboard.internal.KeyboardIconsSet.ICON_UNDEFINED; import static helium314.keyboard.keyboard.internal.KeyboardIconsSet.ICON_UNDEFINED;
import static helium314.keyboard.latin.common.Constants.CODE_OUTPUT_TEXT;
import static helium314.keyboard.latin.common.Constants.CODE_SHIFT;
import static helium314.keyboard.latin.common.Constants.CODE_SWITCH_ALPHA;
import static helium314.keyboard.latin.common.Constants.CODE_SWITCH_ALPHA_SYMBOL;
import static helium314.keyboard.latin.common.Constants.CODE_SWITCH_SYMBOL;
import static helium314.keyboard.latin.common.Constants.CODE_UNSPECIFIED;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -178,7 +173,7 @@ public class Key implements Comparable<Key> {
@Nullable @Nullable
public static OptionalAttributes newInstance(final String outputText, final int altCode, public static OptionalAttributes newInstance(final String outputText, final int altCode,
final int disabledIconId, final int visualInsetsLeft, final int visualInsetsRight) { final int disabledIconId, final int visualInsetsLeft, final int visualInsetsRight) {
if (outputText == null && altCode == CODE_UNSPECIFIED if (outputText == null && altCode == KeyCode.NOT_SPECIFIED
&& disabledIconId == ICON_UNDEFINED && visualInsetsLeft == 0 && disabledIconId == ICON_UNDEFINED && visualInsetsLeft == 0
&& visualInsetsRight == 0) { && visualInsetsRight == 0) {
return null; return null;
@ -214,10 +209,10 @@ public class Key implements Comparable<Key> {
mPopupKeys = null; mPopupKeys = null;
mPopupKeysColumnAndFlags = 0; mPopupKeysColumnAndFlags = 0;
mLabel = label; mLabel = label;
mOptionalAttributes = OptionalAttributes.newInstance(outputText, CODE_UNSPECIFIED, mOptionalAttributes = OptionalAttributes.newInstance(outputText, KeyCode.NOT_SPECIFIED,
ICON_UNDEFINED, 0 /* visualInsetsLeft */, 0 /* visualInsetsRight */); ICON_UNDEFINED, 0 /* visualInsetsLeft */, 0 /* visualInsetsRight */);
mCode = code; mCode = code;
mEnabled = (code != CODE_UNSPECIFIED); mEnabled = (code != KeyCode.NOT_SPECIFIED);
mIconId = iconId; mIconId = iconId;
// Horizontal gap is divided equally to both sides of the key. // Horizontal gap is divided equally to both sides of the key.
mX = x + mHorizontalGap / 2; mX = x + mHorizontalGap / 2;
@ -267,7 +262,7 @@ public class Key implements Comparable<Key> {
public Key(@NonNull final Key key, @Nullable final PopupKeySpec[] popupKeys, public Key(@NonNull final Key key, @Nullable final PopupKeySpec[] popupKeys,
@Nullable final String labelHint, final int backgroundType, final int code, @Nullable final String outputText) { @Nullable final String labelHint, final int backgroundType, final int code, @Nullable final String outputText) {
// Final attributes. // Final attributes.
mCode = outputText == null ? code : CODE_OUTPUT_TEXT; mCode = outputText == null ? code : KeyCode.MULTIPLE_CODE_POINTS;
mLabel = outputText == null ? StringUtils.newSingleCodePointString(code) : outputText; mLabel = outputText == null ? StringUtils.newSingleCodePointString(code) : outputText;
mHintLabel = labelHint; mHintLabel = labelHint;
mLabelFlags = key.mLabelFlags; mLabelFlags = key.mLabelFlags;
@ -284,7 +279,7 @@ public class Key implements Comparable<Key> {
mBackgroundType = backgroundType; mBackgroundType = backgroundType;
mActionFlags = key.mActionFlags; mActionFlags = key.mActionFlags;
mKeyVisualAttributes = key.mKeyVisualAttributes; mKeyVisualAttributes = key.mKeyVisualAttributes;
mOptionalAttributes = outputText == null ? null : Key.OptionalAttributes.newInstance(outputText, CODE_UNSPECIFIED, ICON_UNDEFINED, 0, 0); mOptionalAttributes = outputText == null ? null : Key.OptionalAttributes.newInstance(outputText, KeyCode.NOT_SPECIFIED, ICON_UNDEFINED, 0, 0);
mHashCode = key.mHashCode; mHashCode = key.mHashCode;
// Key state. // Key state.
mPressed = key.mPressed; mPressed = key.mPressed;
@ -442,7 +437,7 @@ public class Key implements Comparable<Key> {
public String toShortString() { public String toShortString() {
final int code = getCode(); final int code = getCode();
if (code == Constants.CODE_OUTPUT_TEXT) { if (code == KeyCode.MULTIPLE_CODE_POINTS) {
return getOutputText(); return getOutputText();
} }
return Constants.printableCode(code); return Constants.printableCode(code);
@ -514,11 +509,11 @@ public class Key implements Comparable<Key> {
} }
public final boolean isShift() { public final boolean isShift() {
return mCode == CODE_SHIFT; return mCode == KeyCode.SHIFT;
} }
public final boolean isModifier() { public final boolean isModifier() {
return mCode == CODE_SHIFT || mCode == CODE_SWITCH_ALPHA_SYMBOL || mCode == CODE_SWITCH_ALPHA || mCode == CODE_SWITCH_SYMBOL; return mCode == KeyCode.SHIFT || mCode == KeyCode.ALPHA_SYMBOL || mCode == KeyCode.ALPHA || mCode == KeyCode.SYMBOL;
} }
public final boolean isRepeatable() { public final boolean isRepeatable() {
@ -704,7 +699,7 @@ public class Key implements Comparable<Key> {
public final int getAltCode() { public final int getAltCode() {
final OptionalAttributes attrs = mOptionalAttributes; final OptionalAttributes attrs = mOptionalAttributes;
return (attrs != null) ? attrs.mAltCode : CODE_UNSPECIFIED; return (attrs != null) ? attrs.mAltCode : KeyCode.NOT_SPECIFIED;
} }
public int getIconId() { public int getIconId() {
@ -948,7 +943,7 @@ public class Key implements Comparable<Key> {
*/ */
protected Spacer(final KeyboardParams params, final int x, final int y, final int width, protected Spacer(final KeyboardParams params, final int x, final int y, final int width,
final int height) { final int height) {
super(null /* label */, ICON_UNDEFINED, CODE_UNSPECIFIED, null /* outputText */, super(null /* label */, ICON_UNDEFINED, KeyCode.NOT_SPECIFIED, null /* outputText */,
null /* hintLabel */, 0 /* labelFlags */, BACKGROUND_TYPE_EMPTY, x, y, width, null /* hintLabel */, 0 /* labelFlags */, BACKGROUND_TYPE_EMPTY, x, y, width,
height, params.mHorizontalGap, params.mVerticalGap); height, params.mHorizontalGap, params.mVerticalGap);
} }
@ -1116,7 +1111,7 @@ public class Key implements Comparable<Key> {
outputText = StringUtils.toTitleCaseOfKeyLabel(outputText, localeForUpcasing); outputText = StringUtils.toTitleCaseOfKeyLabel(outputText, localeForUpcasing);
} }
// Choose the first letter of the label as primary code if not specified. // Choose the first letter of the label as primary code if not specified.
if (code == CODE_UNSPECIFIED && TextUtils.isEmpty(outputText) && !TextUtils.isEmpty(mLabel)) { if (code == KeyCode.NOT_SPECIFIED && TextUtils.isEmpty(outputText) && !TextUtils.isEmpty(mLabel)) {
if (StringUtils.codePointCount(mLabel) == 1) { if (StringUtils.codePointCount(mLabel) == 1) {
// Use the first letter of the hint label if shiftedLetterActivated flag is // Use the first letter of the hint label if shiftedLetterActivated flag is
// specified. // specified.
@ -1130,14 +1125,14 @@ public class Key implements Comparable<Key> {
// In some locale and case, the character might be represented by multiple code // In some locale and case, the character might be represented by multiple code
// points, such as upper case Eszett of German alphabet. // points, such as upper case Eszett of German alphabet.
outputText = mLabel; outputText = mLabel;
mCode = CODE_OUTPUT_TEXT; mCode = KeyCode.MULTIPLE_CODE_POINTS;
} }
} else if (code == CODE_UNSPECIFIED && outputText != null) { } else if (code == KeyCode.NOT_SPECIFIED && outputText != null) {
if (StringUtils.codePointCount(outputText) == 1) { if (StringUtils.codePointCount(outputText) == 1) {
mCode = outputText.codePointAt(0); mCode = outputText.codePointAt(0);
outputText = null; outputText = null;
} else { } else {
mCode = CODE_OUTPUT_TEXT; mCode = KeyCode.MULTIPLE_CODE_POINTS;
} }
} else { } else {
mCode = needsToUpcase ? StringUtils.toTitleCaseOfKeyCode(code, localeForUpcasing) : code; mCode = needsToUpcase ? StringUtils.toTitleCaseOfKeyCode(code, localeForUpcasing) : code;
@ -1145,23 +1140,23 @@ public class Key implements Comparable<Key> {
// action flags don't need to be specified, they can be deduced from the key // action flags don't need to be specified, they can be deduced from the key
if (backgroundType == BACKGROUND_TYPE_SPACEBAR if (backgroundType == BACKGROUND_TYPE_SPACEBAR
|| mCode == Constants.CODE_LANGUAGE_SWITCH || mCode == KeyCode.LANGUAGE_SWITCH
|| (mCode == CODE_SWITCH_ALPHA_SYMBOL && !params.mId.isAlphabetKeyboard()) || (mCode == KeyCode.ALPHA_SYMBOL && !params.mId.isAlphabetKeyboard())
) )
actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS; actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS;
if (mCode <= Constants.CODE_SPACE && mCode != CODE_OUTPUT_TEXT) if (mCode <= Constants.CODE_SPACE && mCode != KeyCode.MULTIPLE_CODE_POINTS)
actionFlags |= ACTION_FLAGS_NO_KEY_PREVIEW; actionFlags |= ACTION_FLAGS_NO_KEY_PREVIEW;
if (mCode == Constants.CODE_DELETE) if (mCode == KeyCode.DELETE)
actionFlags |= ACTION_FLAGS_IS_REPEATABLE; actionFlags |= ACTION_FLAGS_IS_REPEATABLE;
if (mCode == Constants.CODE_SETTINGS || mCode == Constants.CODE_LANGUAGE_SWITCH) if (mCode == KeyCode.SETTINGS || mCode == KeyCode.LANGUAGE_SWITCH)
actionFlags |= ACTION_FLAGS_ALT_CODE_WHILE_TYPING; actionFlags |= ACTION_FLAGS_ALT_CODE_WHILE_TYPING;
mActionFlags = actionFlags; mActionFlags = actionFlags;
final int altCodeInAttr; // settings and language switch keys have alt code space, all others nothing final int altCodeInAttr; // settings and language switch keys have alt code space, all others nothing
if (mCode == Constants.CODE_SETTINGS || mCode == Constants.CODE_LANGUAGE_SWITCH) if (mCode == KeyCode.SETTINGS || mCode == KeyCode.LANGUAGE_SWITCH)
altCodeInAttr = Constants.CODE_SPACE; altCodeInAttr = Constants.CODE_SPACE;
else else
altCodeInAttr = CODE_UNSPECIFIED; altCodeInAttr = KeyCode.NOT_SPECIFIED;
final int altCode = needsToUpcase final int altCode = needsToUpcase
? StringUtils.toTitleCaseOfKeyCode(altCodeInAttr, localeForUpcasing) ? StringUtils.toTitleCaseOfKeyCode(altCodeInAttr, localeForUpcasing)
: altCodeInAttr; : altCodeInAttr;
@ -1206,11 +1201,11 @@ public class Key implements Comparable<Key> {
} }
mLabel = label; mLabel = label;
mOptionalAttributes = code == Constants.CODE_OUTPUT_TEXT mOptionalAttributes = code == KeyCode.MULTIPLE_CODE_POINTS
? OptionalAttributes.newInstance(label, CODE_UNSPECIFIED, ICON_UNDEFINED, 0, 0) ? OptionalAttributes.newInstance(label, KeyCode.NOT_SPECIFIED, ICON_UNDEFINED, 0, 0)
: null; : null;
mCode = code; mCode = code;
mEnabled = (code != CODE_UNSPECIFIED); mEnabled = (code != KeyCode.NOT_SPECIFIED);
mIconId = KeyboardIconsSet.ICON_UNDEFINED; mIconId = KeyboardIconsSet.ICON_UNDEFINED;
mKeyVisualAttributes = null; mKeyVisualAttributes = null;
} }
@ -1220,7 +1215,7 @@ public class Key implements Comparable<Key> {
isSpacer = true; // this is only for spacer! isSpacer = true; // this is only for spacer!
mKeyboardParams = params; mKeyboardParams = params;
mCode = CODE_UNSPECIFIED; mCode = KeyCode.NOT_SPECIFIED;
mLabel = null; mLabel = null;
mHintLabel = null; mHintLabel = null;
mKeyVisualAttributes = null; mKeyVisualAttributes = null;

View file

@ -16,6 +16,7 @@ import com.android.inputmethod.keyboard.ProximityInfo;
import helium314.keyboard.keyboard.internal.KeyVisualAttributes; import helium314.keyboard.keyboard.internal.KeyVisualAttributes;
import helium314.keyboard.keyboard.internal.KeyboardIconsSet; import helium314.keyboard.keyboard.internal.KeyboardIconsSet;
import helium314.keyboard.keyboard.internal.KeyboardParams; import helium314.keyboard.keyboard.internal.KeyboardParams;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.common.Constants; import helium314.keyboard.latin.common.Constants;
import helium314.keyboard.latin.common.CoordinateUtils; import helium314.keyboard.latin.common.CoordinateUtils;
@ -180,7 +181,7 @@ public class Keyboard {
@Nullable @Nullable
public Key getKey(final int code) { public Key getKey(final int code) {
if (code == Constants.CODE_UNSPECIFIED) { if (code == KeyCode.NOT_SPECIFIED) {
return null; return null;
} }
synchronized (mKeyCache) { synchronized (mKeyCache) {

View file

@ -42,6 +42,7 @@ import helium314.keyboard.keyboard.internal.PopupKeySpec;
import helium314.keyboard.keyboard.internal.NonDistinctMultitouchHelper; import helium314.keyboard.keyboard.internal.NonDistinctMultitouchHelper;
import helium314.keyboard.keyboard.internal.SlidingKeyInputDrawingPreview; import helium314.keyboard.keyboard.internal.SlidingKeyInputDrawingPreview;
import helium314.keyboard.keyboard.internal.TimerHandler; import helium314.keyboard.keyboard.internal.TimerHandler;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.R; import helium314.keyboard.latin.R;
import helium314.keyboard.latin.RichInputMethodSubtype; import helium314.keyboard.latin.RichInputMethodSubtype;
import helium314.keyboard.latin.SuggestedWords; import helium314.keyboard.latin.SuggestedWords;
@ -688,7 +689,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
if (keyboard == null) { if (keyboard == null) {
return; return;
} }
final Key shortcutKey = keyboard.getKey(Constants.CODE_SHORTCUT); final Key shortcutKey = keyboard.getKey(KeyCode.VOICE_INPUT);
if (shortcutKey == null) { if (shortcutKey == null) {
return; return;
} }
@ -741,7 +742,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
if (key.isLongPressEnabled() && mHasMultipleEnabledIMEsOrSubtypes) { if (key.isLongPressEnabled() && mHasMultipleEnabledIMEsOrSubtypes) {
drawKeyPopupHint(key, canvas, paint, params); drawKeyPopupHint(key, canvas, paint, params);
} }
} else if (code == Constants.CODE_LANGUAGE_SWITCH) { } else if (code == KeyCode.LANGUAGE_SWITCH) {
drawKeyPopupHint(key, canvas, paint, params); drawKeyPopupHint(key, canvas, paint, params);
} }
} }

View file

@ -11,6 +11,8 @@ import static java.lang.Math.abs;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.os.SystemClock; import android.os.SystemClock;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.utils.Log; import helium314.keyboard.latin.utils.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.inputmethod.InputMethodSubtype; import android.view.inputmethod.InputMethodSubtype;
@ -284,7 +286,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
final boolean altersCode = key.altCodeWhileTyping() && sTimerProxy.isTypingState(); final boolean altersCode = key.altCodeWhileTyping() && sTimerProxy.isTypingState();
final int code = altersCode ? key.getAltCode() : primaryCode; final int code = altersCode ? key.getAltCode() : primaryCode;
if (DEBUG_LISTENER) { if (DEBUG_LISTENER) {
final String output = code == Constants.CODE_OUTPUT_TEXT final String output = code == KeyCode.MULTIPLE_CODE_POINTS
? key.getOutputText() : Constants.printableCode(code); ? key.getOutputText() : Constants.printableCode(code);
Log.d(TAG, String.format(Locale.US, "[%d] onCodeInput: %4d %4d %s%s%s%s", mPointerId, x, y, Log.d(TAG, String.format(Locale.US, "[%d] onCodeInput: %4d %4d %s%s%s%s", mPointerId, x, y,
output, ignoreModifierKey ? " ignoreModifier" : "", output, ignoreModifierKey ? " ignoreModifier" : "",
@ -296,9 +298,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
// Even if the key is disabled, it should respond if it is in the altCodeWhileTyping state. // Even if the key is disabled, it should respond if it is in the altCodeWhileTyping state.
if (key.isEnabled() || altersCode) { if (key.isEnabled() || altersCode) {
sTypingTimeRecorder.onCodeInput(code, eventTime); sTypingTimeRecorder.onCodeInput(code, eventTime);
if (code == Constants.CODE_OUTPUT_TEXT) { if (code == KeyCode.MULTIPLE_CODE_POINTS) {
sListener.onTextInput(key.getOutputText()); sListener.onTextInput(key.getOutputText());
} else if (code != Constants.CODE_UNSPECIFIED) { } else if (code != KeyCode.NOT_SPECIFIED) {
if (mKeyboard.hasProximityCharsCorrection(code)) { if (mKeyboard.hasProximityCharsCorrection(code)) {
sListener.onCodeInput(code, x, y, isKeyRepeat); sListener.onCodeInput(code, x, y, isKeyRepeat);
} else { } else {
@ -935,7 +937,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
return; return;
} }
if (oldKey != null && oldKey.getCode() == Constants.CODE_DELETE && sv.mDeleteSwipeEnabled) { if (oldKey != null && oldKey.getCode() == KeyCode.DELETE && sv.mDeleteSwipeEnabled) {
// Delete slider // Delete slider
int steps = (x - mStartX) / sPointerStep; int steps = (x - mStartX) / sPointerStep;
if (abs(steps) > 2 || (mCursorMoved && steps != 0)) { if (abs(steps) > 2 || (mCursorMoved && steps != 0)) {
@ -1023,7 +1025,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
// Release the last pressed key. // Release the last pressed key.
setReleasedKeyGraphics(currentKey, true); setReleasedKeyGraphics(currentKey, true);
if(mCursorMoved && currentKey.getCode() == Constants.CODE_DELETE) { if(mCursorMoved && currentKey.getCode() == KeyCode.DELETE) {
sListener.onUpWithDeletePointerActive(); sListener.onUpWithDeletePointerActive();
} }
@ -1103,7 +1105,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
return; return;
} }
final int code = key.getCode(); final int code = key.getCode();
if (code == Constants.CODE_LANGUAGE_SWITCH if (code == KeyCode.LANGUAGE_SWITCH
|| (code == Constants.CODE_SPACE && Settings.getInstance().getCurrent().mSpaceForLangChange) || (code == Constants.CODE_SPACE && Settings.getInstance().getCurrent().mSpaceForLangChange)
) { ) {
// Long pressing the space key invokes IME switcher dialog. // Long pressing the space key invokes IME switcher dialog.
@ -1113,8 +1115,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
return; return;
} }
} }
if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) { if (code == KeyCode.ALPHA_SYMBOL) {
sListener.onCodeInput(Constants.CODE_SWITCH_NUMPAD, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false); sListener.onCodeInput(KeyCode.NUMPAD, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false);
return; return;
} }
@ -1207,7 +1209,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
} }
private int getLongPressTimeout(final int code) { private int getLongPressTimeout(final int code) {
if (code == Constants.CODE_SHIFT) { if (code == KeyCode.SHIFT) {
return sParams.mLongPressShiftLockTimeout; return sParams.mLongPressShiftLockTimeout;
} }
final int longpressTimeout = Settings.getInstance().getCurrent().mKeyLongpressTimeout; final int longpressTimeout = Settings.getInstance().getCurrent().mKeyLongpressTimeout;

View file

@ -22,6 +22,7 @@ import helium314.keyboard.accessibility.AccessibilityUtils;
import helium314.keyboard.accessibility.PopupKeysKeyboardAccessibilityDelegate; import helium314.keyboard.accessibility.PopupKeysKeyboardAccessibilityDelegate;
import helium314.keyboard.keyboard.emoji.OnKeyEventListener; import helium314.keyboard.keyboard.emoji.OnKeyEventListener;
import helium314.keyboard.keyboard.internal.KeyDrawParams; import helium314.keyboard.keyboard.internal.KeyDrawParams;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.R; import helium314.keyboard.latin.R;
import helium314.keyboard.latin.common.Constants; import helium314.keyboard.latin.common.Constants;
import helium314.keyboard.latin.common.CoordinateUtils; import helium314.keyboard.latin.common.CoordinateUtils;
@ -205,9 +206,9 @@ public class PopupKeysKeyboardView extends KeyboardView implements PopupKeysPane
protected void onKeyInput(final Key key, final int x, final int y) { protected void onKeyInput(final Key key, final int x, final int y) {
if (mListener != null) { if (mListener != null) {
final int code = key.getCode(); final int code = key.getCode();
if (code == Constants.CODE_OUTPUT_TEXT) { if (code == KeyCode.MULTIPLE_CODE_POINTS) {
mListener.onTextInput(mCurrentKey.getOutputText()); mListener.onTextInput(mCurrentKey.getOutputText());
} else if (code != Constants.CODE_UNSPECIFIED) { } else if (code != KeyCode.NOT_SPECIFIED) {
if (getKeyboard().hasProximityCharsCorrection(code)) { if (getKeyboard().hasProximityCharsCorrection(code)) {
mListener.onCodeInput(code, x, y, false /* isKeyRepeat */); mListener.onCodeInput(code, x, y, false /* isKeyRepeat */);
} else { } else {

View file

@ -18,6 +18,7 @@ import helium314.keyboard.keyboard.KeyboardSwitcher
import helium314.keyboard.keyboard.internal.KeyDrawParams import helium314.keyboard.keyboard.internal.KeyDrawParams
import helium314.keyboard.keyboard.internal.KeyVisualAttributes import helium314.keyboard.keyboard.internal.KeyVisualAttributes
import helium314.keyboard.keyboard.internal.KeyboardIconsSet import helium314.keyboard.keyboard.internal.KeyboardIconsSet
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
import helium314.keyboard.latin.ClipboardHistoryManager import helium314.keyboard.latin.ClipboardHistoryManager
import helium314.keyboard.latin.R import helium314.keyboard.latin.R
import helium314.keyboard.latin.common.ColorType import helium314.keyboard.latin.common.ColorType
@ -102,12 +103,12 @@ class ClipboardHistoryView @JvmOverloads constructor(
} }
alphabetKey = findViewById(R.id.key_alphabet) alphabetKey = findViewById(R.id.key_alphabet)
alphabetKey.setBackgroundResource(functionalKeyBackgroundId) alphabetKey.setBackgroundResource(functionalKeyBackgroundId)
alphabetKey.tag = Constants.CODE_SWITCH_ALPHA alphabetKey.tag = KeyCode.ALPHA
alphabetKey.setOnTouchListener(this) alphabetKey.setOnTouchListener(this)
alphabetKey.setOnClickListener(this) alphabetKey.setOnClickListener(this)
deleteKey = findViewById(R.id.key_delete) deleteKey = findViewById(R.id.key_delete)
deleteKey.setBackgroundResource(functionalKeyBackgroundId) deleteKey.setBackgroundResource(functionalKeyBackgroundId)
deleteKey.tag = Constants.CODE_DELETE deleteKey.tag = KeyCode.DELETE
deleteKey.setOnTouchListener(this) deleteKey.setOnTouchListener(this)
deleteKey.setOnClickListener(this) deleteKey.setOnClickListener(this)
spacebar = findViewById(R.id.key_space) spacebar = findViewById(R.id.key_space)
@ -240,13 +241,13 @@ class ClipboardHistoryView @JvmOverloads constructor(
} }
override fun onKeyDown(clipId: Long) { override fun onKeyDown(clipId: Long) {
keyboardActionListener?.onPressKey(Constants.CODE_UNSPECIFIED, 0, true) keyboardActionListener?.onPressKey(KeyCode.NOT_SPECIFIED, 0, true)
} }
override fun onKeyUp(clipId: Long) { override fun onKeyUp(clipId: Long) {
val clipContent = clipboardHistoryManager?.getHistoryEntryContent(clipId) val clipContent = clipboardHistoryManager?.getHistoryEntryContent(clipId)
keyboardActionListener?.onTextInput(clipContent?.content.toString()) keyboardActionListener?.onTextInput(clipContent?.content.toString())
keyboardActionListener?.onReleaseKey(Constants.CODE_UNSPECIFIED, false) keyboardActionListener?.onReleaseKey(KeyCode.NOT_SPECIFIED, false)
} }
override fun onClipboardHistoryEntryAdded(at: Int) { override fun onClipboardHistoryEntryAdded(at: Int) {

View file

@ -32,6 +32,7 @@ import helium314.keyboard.keyboard.KeyboardView;
import helium314.keyboard.keyboard.internal.KeyDrawParams; import helium314.keyboard.keyboard.internal.KeyDrawParams;
import helium314.keyboard.keyboard.internal.KeyVisualAttributes; import helium314.keyboard.keyboard.internal.KeyVisualAttributes;
import helium314.keyboard.keyboard.internal.KeyboardIconsSet; import helium314.keyboard.keyboard.internal.KeyboardIconsSet;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.AudioAndHapticFeedbackManager; import helium314.keyboard.latin.AudioAndHapticFeedbackManager;
import helium314.keyboard.latin.R; import helium314.keyboard.latin.R;
import helium314.keyboard.latin.RichInputMethodSubtype; import helium314.keyboard.latin.RichInputMethodSubtype;
@ -225,7 +226,7 @@ public final class EmojiPalettesView extends LinearLayout
mDeleteKey = findViewById(R.id.key_delete); mDeleteKey = findViewById(R.id.key_delete);
mDeleteKey.setBackgroundResource(mFunctionalKeyBackgroundId); mDeleteKey.setBackgroundResource(mFunctionalKeyBackgroundId);
mColors.setColor(mDeleteKey, ColorType.KEY_ICON); mColors.setColor(mDeleteKey, ColorType.KEY_ICON);
mDeleteKey.setTag(Constants.CODE_DELETE); mDeleteKey.setTag(KeyCode.DELETE);
mDeleteKey.setOnTouchListener(mDeleteKeyOnTouchListener); mDeleteKey.setOnTouchListener(mDeleteKeyOnTouchListener);
// {@link #mAlphabetKeyLeft} and spaceKey depend on // {@link #mAlphabetKeyLeft} and spaceKey depend on
@ -237,7 +238,7 @@ public final class EmojiPalettesView extends LinearLayout
// {@link #startEmojiPalettes(String,int,float,Typeface)}. // {@link #startEmojiPalettes(String,int,float,Typeface)}.
mAlphabetKeyLeft = findViewById(R.id.key_alphabet); mAlphabetKeyLeft = findViewById(R.id.key_alphabet);
mAlphabetKeyLeft.setBackgroundResource(mFunctionalKeyBackgroundId); mAlphabetKeyLeft.setBackgroundResource(mFunctionalKeyBackgroundId);
mAlphabetKeyLeft.setTag(Constants.CODE_SWITCH_ALPHA); mAlphabetKeyLeft.setTag(KeyCode.ALPHA);
mAlphabetKeyLeft.setOnTouchListener(this); mAlphabetKeyLeft.setOnTouchListener(this);
mAlphabetKeyLeft.setOnClickListener(this); mAlphabetKeyLeft.setOnClickListener(this);
mSpacebar = findViewById(R.id.key_space); mSpacebar = findViewById(R.id.key_space);
@ -297,7 +298,7 @@ public final class EmojiPalettesView extends LinearLayout
public void onClick(View v) { public void onClick(View v) {
final Object tag = v.getTag(); final Object tag = v.getTag();
if (tag instanceof Long) { if (tag instanceof Long) {
AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback(Constants.CODE_UNSPECIFIED, this); AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback(KeyCode.NOT_SPECIFIED, this);
final int categoryId = ((Long) tag).intValue(); final int categoryId = ((Long) tag).intValue();
if (categoryId != mEmojiCategory.getCurrentCategoryId()) { if (categoryId != mEmojiCategory.getCurrentCategoryId()) {
setCurrentCategoryAndPageId(categoryId, 0, false); setCurrentCategoryAndPageId(categoryId, 0, false);
@ -333,7 +334,7 @@ public final class EmojiPalettesView extends LinearLayout
public void onReleaseKey(final Key key) { public void onReleaseKey(final Key key) {
mEmojiPalettesAdapter.addRecentKey(key); mEmojiPalettesAdapter.addRecentKey(key);
final int code = key.getCode(); final int code = key.getCode();
if (code == Constants.CODE_OUTPUT_TEXT) { if (code == KeyCode.MULTIPLE_CODE_POINTS) {
mKeyboardActionListener.onTextInput(key.getOutputText()); mKeyboardActionListener.onTextInput(key.getOutputText());
} else { } else {
mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE, false); mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE, false);
@ -453,13 +454,13 @@ public final class EmojiPalettesView extends LinearLayout
} }
private void onTouchDown(final View v) { private void onTouchDown(final View v) {
mKeyboardActionListener.onPressKey(Constants.CODE_DELETE, 0, true); mKeyboardActionListener.onPressKey(KeyCode.DELETE, 0, true);
v.setPressed(true /* pressed */); v.setPressed(true /* pressed */);
} }
private void onTouchUp(final View v) { private void onTouchUp(final View v) {
mKeyboardActionListener.onCodeInput(Constants.CODE_DELETE, NOT_A_COORDINATE, NOT_A_COORDINATE, false); mKeyboardActionListener.onCodeInput(KeyCode.DELETE, NOT_A_COORDINATE, NOT_A_COORDINATE, false);
mKeyboardActionListener.onReleaseKey(Constants.CODE_DELETE, false); mKeyboardActionListener.onReleaseKey(KeyCode.DELETE, false);
v.setPressed(false /* pressed */); v.setPressed(false /* pressed */);
} }

View file

@ -8,6 +8,7 @@ package helium314.keyboard.keyboard.internal;
import android.text.TextUtils; import android.text.TextUtils;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.common.Constants; import helium314.keyboard.latin.common.Constants;
import helium314.keyboard.latin.common.StringUtils; import helium314.keyboard.latin.common.StringUtils;
@ -79,7 +80,7 @@ public final class CodesArrayParser {
if (codeSpec.indexOf(COMMA) < 0) { if (codeSpec.indexOf(COMMA) < 0) {
return Integer.parseInt(codeSpec, BASE_HEX); return Integer.parseInt(codeSpec, BASE_HEX);
} }
return Constants.CODE_OUTPUT_TEXT; return KeyCode.MULTIPLE_CODE_POINTS;
} }
public static String parseOutputText(final String codesArraySpec) { public static String parseOutputText(final String codesArraySpec) {

View file

@ -6,13 +6,11 @@
package helium314.keyboard.keyboard.internal; package helium314.keyboard.keyboard.internal;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.common.Constants; import helium314.keyboard.latin.common.Constants;
import helium314.keyboard.latin.common.StringUtils; import helium314.keyboard.latin.common.StringUtils;
import helium314.keyboard.latin.define.DebugFlags; import helium314.keyboard.latin.define.DebugFlags;
import static helium314.keyboard.latin.common.Constants.CODE_OUTPUT_TEXT;
import static helium314.keyboard.latin.common.Constants.CODE_UNSPECIFIED;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -184,12 +182,12 @@ public final class KeySpecParser {
public static int getCode(@Nullable final String keySpec) { public static int getCode(@Nullable final String keySpec) {
if (keySpec == null) { if (keySpec == null) {
// TODO: Throw {@link KeySpecParserError} once Key.keyLabel attribute becomes mandatory. // TODO: Throw {@link KeySpecParserError} once Key.keyLabel attribute becomes mandatory.
return CODE_UNSPECIFIED; return KeyCode.NOT_SPECIFIED;
} }
final int labelEnd = indexOfLabelEnd(keySpec); final int labelEnd = indexOfLabelEnd(keySpec);
if (hasCode(keySpec, labelEnd)) { if (hasCode(keySpec, labelEnd)) {
checkDoubleLabelEnd(keySpec, labelEnd); checkDoubleLabelEnd(keySpec, labelEnd);
return parseCode(getAfterLabelEnd(keySpec, labelEnd), CODE_UNSPECIFIED); return parseCode(getAfterLabelEnd(keySpec, labelEnd), KeyCode.NOT_SPECIFIED);
} }
final String outputText = getOutputTextInternal(keySpec, labelEnd); final String outputText = getOutputTextInternal(keySpec, labelEnd);
if (outputText != null) { if (outputText != null) {
@ -198,16 +196,16 @@ public final class KeySpecParser {
if (StringUtils.codePointCount(outputText) == 1) { if (StringUtils.codePointCount(outputText) == 1) {
return outputText.codePointAt(0); return outputText.codePointAt(0);
} }
return CODE_OUTPUT_TEXT; return KeyCode.MULTIPLE_CODE_POINTS;
} }
final String label = getLabel(keySpec); final String label = getLabel(keySpec);
if (label == null) { if (label == null) {
if (DebugFlags.DEBUG_ENABLED) if (DebugFlags.DEBUG_ENABLED)
throw new KeySpecParserError("Empty label: " + keySpec); throw new KeySpecParserError("Empty label: " + keySpec);
else return CODE_OUTPUT_TEXT; else return KeyCode.MULTIPLE_CODE_POINTS;
} }
// Code is automatically generated for one letter label. // Code is automatically generated for one letter label.
return (StringUtils.codePointCount(label) == 1) ? label.codePointAt(0) : CODE_OUTPUT_TEXT; return (StringUtils.codePointCount(label) == 1) ? label.codePointAt(0) : KeyCode.MULTIPLE_CODE_POINTS;
} }
public static int parseCode(@Nullable final String text, final int defaultCode) { public static int parseCode(@Nullable final String text, final int defaultCode) {

View file

@ -16,6 +16,7 @@ import helium314.keyboard.keyboard.KeyboardId
import helium314.keyboard.keyboard.internal.keyboard_parser.EmojiParser import helium314.keyboard.keyboard.internal.keyboard_parser.EmojiParser
import helium314.keyboard.keyboard.internal.keyboard_parser.KeyboardParser import helium314.keyboard.keyboard.internal.keyboard_parser.KeyboardParser
import helium314.keyboard.keyboard.internal.keyboard_parser.addLocaleKeyTextsToParams import helium314.keyboard.keyboard.internal.keyboard_parser.addLocaleKeyTextsToParams
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
import helium314.keyboard.latin.R import helium314.keyboard.latin.R
import helium314.keyboard.latin.common.Constants import helium314.keyboard.latin.common.Constants
import helium314.keyboard.latin.define.DebugFlags import helium314.keyboard.latin.define.DebugFlags
@ -210,7 +211,7 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
// todo: this assumes fixed layout for symbols keys, which will change soon! // todo: this assumes fixed layout for symbols keys, which will change soon!
private fun reduceSymbolAndActionKeyWidth(row: ArrayList<KeyParams>) { private fun reduceSymbolAndActionKeyWidth(row: ArrayList<KeyParams>) {
val spaceKey = row.first { it.mCode == Constants.CODE_SPACE } val spaceKey = row.first { it.mCode == Constants.CODE_SPACE }
val symbolKey = row.firstOrNull { it.mCode == Constants.CODE_SWITCH_ALPHA_SYMBOL } val symbolKey = row.firstOrNull { it.mCode == KeyCode.ALPHA_SYMBOL }
val symbolKeyWidth = symbolKey?.mRelativeWidth ?: 0f val symbolKeyWidth = symbolKey?.mRelativeWidth ?: 0f
if (symbolKeyWidth > mParams.mDefaultRelativeKeyWidth) { if (symbolKeyWidth > mParams.mDefaultRelativeKeyWidth) {
val widthToChange = symbolKey!!.mRelativeWidth - mParams.mDefaultRelativeKeyWidth val widthToChange = symbolKey!!.mRelativeWidth - mParams.mDefaultRelativeKeyWidth

View file

@ -6,6 +6,7 @@
package helium314.keyboard.keyboard.internal; package helium314.keyboard.keyboard.internal;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.common.Constants; import helium314.keyboard.latin.common.Constants;
import java.util.HashMap; import java.util.HashMap;
@ -37,7 +38,7 @@ public final class KeyboardCodesSet {
"key_output_text", "key_output_text",
"key_delete", "key_delete",
"key_settings", "key_settings",
"key_shortcut", "key_voice_input",
"key_action_next", "key_action_next",
"key_action_previous", "key_action_previous",
"key_shift_enter", "key_shift_enter",
@ -55,26 +56,26 @@ public final class KeyboardCodesSet {
Constants.CODE_TAB, Constants.CODE_TAB,
Constants.CODE_ENTER, Constants.CODE_ENTER,
Constants.CODE_SPACE, Constants.CODE_SPACE,
Constants.CODE_SHIFT, KeyCode.SHIFT,
Constants.CODE_CAPSLOCK, KeyCode.CAPS_LOCK,
Constants.CODE_SWITCH_ALPHA_SYMBOL, KeyCode.ALPHA_SYMBOL,
Constants.CODE_SWITCH_ALPHA, KeyCode.ALPHA,
Constants.CODE_SWITCH_SYMBOL, KeyCode.SYMBOL,
Constants.CODE_OUTPUT_TEXT, KeyCode.MULTIPLE_CODE_POINTS,
Constants.CODE_DELETE, KeyCode.DELETE,
Constants.CODE_SETTINGS, KeyCode.SETTINGS,
Constants.CODE_SHORTCUT, KeyCode.VOICE_INPUT,
Constants.CODE_ACTION_NEXT, KeyCode.ACTION_NEXT,
Constants.CODE_ACTION_PREVIOUS, KeyCode.ACTION_PREVIOUS,
Constants.CODE_SHIFT_ENTER, KeyCode.SHIFT_ENTER,
Constants.CODE_LANGUAGE_SWITCH, KeyCode.LANGUAGE_SWITCH,
Constants.CODE_EMOJI, KeyCode.EMOJI,
Constants.CODE_UNSPECIFIED, KeyCode.NOT_SPECIFIED,
Constants.CODE_CLIPBOARD, KeyCode.CLIPBOARD,
Constants.CODE_SWITCH_NUMPAD, KeyCode.NUMPAD,
Constants.CODE_START_ONE_HANDED_MODE, KeyCode.START_ONE_HANDED_MODE,
Constants.CODE_STOP_ONE_HANDED_MODE, KeyCode.STOP_ONE_HANDED_MODE,
Constants.CODE_SWITCH_ONE_HANDED_MODE KeyCode.SWITCH_ONE_HANDED_MODE
}; };
static { static {

View file

@ -17,6 +17,7 @@ import androidx.annotation.Nullable;
import helium314.keyboard.keyboard.Key; import helium314.keyboard.keyboard.Key;
import helium314.keyboard.keyboard.KeyboardId; import helium314.keyboard.keyboard.KeyboardId;
import helium314.keyboard.keyboard.internal.keyboard_parser.LocaleKeyboardInfos; import helium314.keyboard.keyboard.internal.keyboard_parser.LocaleKeyboardInfos;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.R; import helium314.keyboard.latin.R;
import helium314.keyboard.latin.common.Constants; import helium314.keyboard.latin.common.Constants;
import helium314.keyboard.latin.settings.Settings; import helium314.keyboard.latin.settings.Settings;
@ -134,7 +135,7 @@ public class KeyboardParams {
return; return;
} }
updateHistogram(key); updateHistogram(key);
if (key.getCode() == Constants.CODE_SHIFT) { if (key.getCode() == KeyCode.SHIFT) {
mShiftKeys.add(key); mShiftKeys.add(key);
} }
if (key.altCodeWhileTyping()) { if (key.altCodeWhileTyping()) {

View file

@ -7,6 +7,8 @@
package helium314.keyboard.keyboard.internal; package helium314.keyboard.keyboard.internal;
import android.text.TextUtils; import android.text.TextUtils;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.utils.Log; import helium314.keyboard.latin.utils.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -411,21 +413,21 @@ public final class KeyboardState {
+ " single=" + isSinglePointer + " single=" + isSinglePointer
+ " " + stateToString(autoCapsFlags, recapitalizeMode)); + " " + stateToString(autoCapsFlags, recapitalizeMode));
} }
if (code != Constants.CODE_SHIFT) { if (code != KeyCode.SHIFT) {
// Because the double tap shift key timer is to detect two consecutive shift key press, // Because the double tap shift key timer is to detect two consecutive shift key press,
// it should be canceled when a non-shift key is pressed. // it should be canceled when a non-shift key is pressed.
mSwitchActions.cancelDoubleTapShiftKeyTimer(); mSwitchActions.cancelDoubleTapShiftKeyTimer();
} }
if (code == Constants.CODE_SHIFT) { if (code == KeyCode.SHIFT) {
onPressShift(); onPressShift();
} else if (code == Constants.CODE_CAPSLOCK) { } else if (code == KeyCode.CAPS_LOCK) {
// Nothing to do here. See {@link #onReleaseKey(int,boolean)}. // Nothing to do here. See {@link #onReleaseKey(int,boolean)}.
} else if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) { } else if (code == KeyCode.ALPHA_SYMBOL) {
onPressAlphaSymbol(autoCapsFlags, recapitalizeMode); onPressAlphaSymbol(autoCapsFlags, recapitalizeMode);
} else if (code == Constants.CODE_SWITCH_SYMBOL) { } else if (code == KeyCode.SYMBOL) {
// don't start sliding, causes issues with fully customizable layouts // don't start sliding, causes issues with fully customizable layouts
// (also does not allow chording, but can be fixed later) // (also does not allow chording, but can be fixed later)
} else if (code == Constants.CODE_SWITCH_ALPHA) { } else if (code == KeyCode.ALPHA) {
// don't start sliding, causes issues with fully customizable layouts // don't start sliding, causes issues with fully customizable layouts
// (also does not allow chording, but can be fixed later) // (also does not allow chording, but can be fixed later)
} else { } else {
@ -457,15 +459,15 @@ public final class KeyboardState {
+ " sliding=" + withSliding + " sliding=" + withSliding
+ " " + stateToString(autoCapsFlags, recapitalizeMode)); + " " + stateToString(autoCapsFlags, recapitalizeMode));
} }
if (code == Constants.CODE_SHIFT) { if (code == KeyCode.SHIFT) {
onReleaseShift(withSliding, autoCapsFlags, recapitalizeMode); onReleaseShift(withSliding, autoCapsFlags, recapitalizeMode);
} else if (code == Constants.CODE_CAPSLOCK) { } else if (code == KeyCode.CAPS_LOCK) {
setShiftLocked(!mAlphabetShiftState.isShiftLocked()); setShiftLocked(!mAlphabetShiftState.isShiftLocked());
} else if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) { } else if (code == KeyCode.ALPHA_SYMBOL) {
onReleaseAlphaSymbol(withSliding, autoCapsFlags, recapitalizeMode); onReleaseAlphaSymbol(withSliding, autoCapsFlags, recapitalizeMode);
} else if (code == Constants.CODE_SWITCH_SYMBOL) { } else if (code == KeyCode.SYMBOL) {
onReleaseSymbol(withSliding, autoCapsFlags, recapitalizeMode); onReleaseSymbol(withSliding, autoCapsFlags, recapitalizeMode);
} else if (code == Constants.CODE_SWITCH_ALPHA) { } else if (code == KeyCode.ALPHA) {
onReleaseAlpha(withSliding, autoCapsFlags, recapitalizeMode); onReleaseAlpha(withSliding, autoCapsFlags, recapitalizeMode);
} }
} }
@ -698,7 +700,7 @@ public final class KeyboardState {
switch (mSwitchState) { switch (mSwitchState) {
case SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL: case SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL:
if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) { if (code == KeyCode.ALPHA_SYMBOL) {
// Detected only the mode change key has been pressed, and then released. // Detected only the mode change key has been pressed, and then released.
if (mMode == MODE_ALPHABET) { if (mMode == MODE_ALPHABET) {
mSwitchState = SWITCH_STATE_ALPHA; mSwitchState = SWITCH_STATE_ALPHA;
@ -708,7 +710,7 @@ public final class KeyboardState {
} }
break; break;
case SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE: case SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE:
if (code == Constants.CODE_SHIFT) { if (code == KeyCode.SHIFT) {
// Detected only the shift key has been pressed on symbol layout, and then // Detected only the shift key has been pressed on symbol layout, and then
// released. // released.
mSwitchState = SWITCH_STATE_SYMBOL_BEGIN; mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
@ -727,7 +729,7 @@ public final class KeyboardState {
break; break;
} }
if (!isSpaceOrEnter(code) && (Constants.isLetterCode(code) if (!isSpaceOrEnter(code) && (Constants.isLetterCode(code)
|| code == Constants.CODE_OUTPUT_TEXT)) { || code == KeyCode.MULTIPLE_CODE_POINTS)) {
mSwitchState = SWITCH_STATE_SYMBOL; mSwitchState = SWITCH_STATE_SYMBOL;
} }
// Switch back to alpha keyboard mode if user types one or more non-space/enter // Switch back to alpha keyboard mode if user types one or more non-space/enter
@ -750,25 +752,25 @@ public final class KeyboardState {
// If the code is a letter, update keyboard shift state. // If the code is a letter, update keyboard shift state.
if (Constants.isLetterCode(code)) { if (Constants.isLetterCode(code)) {
updateAlphabetShiftState(autoCapsFlags, recapitalizeMode); updateAlphabetShiftState(autoCapsFlags, recapitalizeMode);
} else if (code == Constants.CODE_EMOJI) { } else if (code == KeyCode.EMOJI) {
setEmojiKeyboard(); setEmojiKeyboard();
} else if (code == Constants.CODE_SWITCH_ALPHA) { } else if (code == KeyCode.ALPHA) {
setAlphabetKeyboard(autoCapsFlags, recapitalizeMode); setAlphabetKeyboard(autoCapsFlags, recapitalizeMode);
} else if (code == Constants.CODE_CLIPBOARD) { } else if (code == KeyCode.CLIPBOARD) {
// Note: Printing clipboard content is handled in // Note: Printing clipboard content is handled in
// {@link InputLogic#handleFunctionalEvent(Event,InputTransaction,int,LatinIME.UIHandler)}. // {@link InputLogic#handleFunctionalEvent(Event,InputTransaction,int,LatinIME.UIHandler)}.
if (Settings.getInstance().getCurrent().mClipboardHistoryEnabled) { if (Settings.getInstance().getCurrent().mClipboardHistoryEnabled) {
setClipboardKeyboard(); setClipboardKeyboard();
} }
} else if (code == Constants.CODE_SWITCH_NUMPAD) { } else if (code == KeyCode.NUMPAD) {
setNumpadKeyboard(); setNumpadKeyboard();
} else if (code == Constants.CODE_SWITCH_SYMBOL) { } else if (code == KeyCode.SYMBOL) {
setSymbolsKeyboard(); setSymbolsKeyboard();
} else if (code == Constants.CODE_START_ONE_HANDED_MODE) { } else if (code == KeyCode.START_ONE_HANDED_MODE) {
setOneHandedModeEnabled(true); setOneHandedModeEnabled(true);
} else if (code == Constants.CODE_STOP_ONE_HANDED_MODE) { } else if (code == KeyCode.STOP_ONE_HANDED_MODE) {
setOneHandedModeEnabled(false); setOneHandedModeEnabled(false);
} else if (code == Constants.CODE_SWITCH_ONE_HANDED_MODE) { } else if (code == KeyCode.SWITCH_ONE_HANDED_MODE) {
switchOneHandedMode(); switchOneHandedMode();
} }
} }

View file

@ -13,6 +13,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import helium314.keyboard.keyboard.Key; import helium314.keyboard.keyboard.Key;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.common.CollectionUtils; import helium314.keyboard.latin.common.CollectionUtils;
import helium314.keyboard.latin.common.Constants; import helium314.keyboard.latin.common.Constants;
import helium314.keyboard.latin.common.StringUtils; import helium314.keyboard.latin.common.StringUtils;
@ -51,10 +52,10 @@ public final class PopupKeySpec {
final int codeInSpec = KeySpecParser.getCode(popupKeySpec); final int codeInSpec = KeySpecParser.getCode(popupKeySpec);
final int code = needsToUpperCase ? StringUtils.toTitleCaseOfKeyCode(codeInSpec, locale) final int code = needsToUpperCase ? StringUtils.toTitleCaseOfKeyCode(codeInSpec, locale)
: codeInSpec; : codeInSpec;
if (code == Constants.CODE_UNSPECIFIED) { if (code == KeyCode.NOT_SPECIFIED) {
// Some letter, for example German Eszett (U+00DF: "ß"), has multiple characters // Some letter, for example German Eszett (U+00DF: "ß"), has multiple characters
// upper case representation ("SS"). // upper case representation ("SS").
mCode = Constants.CODE_OUTPUT_TEXT; mCode = KeyCode.MULTIPLE_CODE_POINTS;
mOutputText = mLabel; mOutputText = mLabel;
} else { } else {
mCode = code; mCode = code;
@ -103,7 +104,7 @@ public final class PopupKeySpec {
public String toString() { public String toString() {
final String label = (mIconId == KeyboardIconsSet.ICON_UNDEFINED ? mLabel final String label = (mIconId == KeyboardIconsSet.ICON_UNDEFINED ? mLabel
: KeyboardIconsSet.PREFIX_ICON + KeyboardIconsSet.getIconName(mIconId)); : KeyboardIconsSet.PREFIX_ICON + KeyboardIconsSet.getIconName(mIconId));
final String output = (mCode == Constants.CODE_OUTPUT_TEXT ? mOutputText final String output = (mCode == KeyCode.MULTIPLE_CODE_POINTS ? mOutputText
: Constants.printableCode(mCode)); : Constants.printableCode(mCode));
if (StringUtils.codePointCount(label) == 1 && label.codePointAt(0) == mCode) { if (StringUtils.codePointCount(label) == 1 && label.codePointAt(0) == mCode) {
return output; return output;
@ -119,7 +120,7 @@ public final class PopupKeySpec {
final int code = key.getCode(); final int code = key.getCode();
if (code > 32) { if (code > 32) {
mCodes.put(code, 0); mCodes.put(code, 0);
} else if (code == Constants.CODE_OUTPUT_TEXT) { } else if (code == KeyCode.MULTIPLE_CODE_POINTS) {
mTexts.add(key.getOutputText()); mTexts.add(key.getOutputText());
} }
} }
@ -128,7 +129,7 @@ public final class PopupKeySpec {
final int code = popupKey.mCode; final int code = popupKey.mCode;
if (mCodes.indexOfKey(code) >= 0) { if (mCodes.indexOfKey(code) >= 0) {
return true; return true;
} else return code == Constants.CODE_OUTPUT_TEXT && mTexts.contains(popupKey.mOutputText); } else return code == KeyCode.MULTIPLE_CODE_POINTS && mTexts.contains(popupKey.mOutputText);
} }
} }

View file

@ -14,6 +14,7 @@ import androidx.annotation.NonNull;
import helium314.keyboard.keyboard.Key; import helium314.keyboard.keyboard.Key;
import helium314.keyboard.keyboard.PointerTracker; import helium314.keyboard.keyboard.PointerTracker;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.common.Constants; import helium314.keyboard.latin.common.Constants;
import helium314.keyboard.latin.utils.LeakGuardHandlerWrapper; import helium314.keyboard.latin.utils.LeakGuardHandlerWrapper;
@ -104,7 +105,7 @@ public final class TimerHandler extends LeakGuardHandlerWrapper<DrawingProxy>
} }
// Use a separate message id for long pressing shift key, because long press shift key // Use a separate message id for long pressing shift key, because long press shift key
// timers should be canceled when other key is pressed. // timers should be canceled when other key is pressed.
final int messageId = (key.getCode() == Constants.CODE_SHIFT) final int messageId = (key.getCode() == KeyCode.SHIFT)
? MSG_LONGPRESS_SHIFT_KEY : MSG_LONGPRESS_KEY; ? MSG_LONGPRESS_SHIFT_KEY : MSG_LONGPRESS_KEY;
sendMessageDelayed(obtainMessage(messageId, tracker), delay); sendMessageDelayed(obtainMessage(messageId, tracker), delay);
} }

View file

@ -7,6 +7,7 @@ import helium314.keyboard.keyboard.Key
import helium314.keyboard.keyboard.Key.KeyParams import helium314.keyboard.keyboard.Key.KeyParams
import helium314.keyboard.keyboard.KeyboardId import helium314.keyboard.keyboard.KeyboardId
import helium314.keyboard.keyboard.internal.KeyboardParams import helium314.keyboard.keyboard.internal.KeyboardParams
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
import helium314.keyboard.latin.R import helium314.keyboard.latin.R
import helium314.keyboard.latin.common.Constants import helium314.keyboard.latin.common.Constants
import helium314.keyboard.latin.common.StringUtils import helium314.keyboard.latin.common.StringUtils
@ -66,7 +67,7 @@ class EmojiParser(private val params: KeyboardParams, private val context: Conte
val specAndSdk = spec.split("||") val specAndSdk = spec.split("||")
if (specAndSdk.getOrNull(1)?.toIntOrNull()?.let { it > Build.VERSION.SDK_INT } == true) return null if (specAndSdk.getOrNull(1)?.toIntOrNull()?.let { it > Build.VERSION.SDK_INT } == true) return null
if ("," !in specAndSdk.first()) { if ("," !in specAndSdk.first()) {
val code = specAndSdk.first().toIntOrNull(16) ?: return specAndSdk.first() to Constants.CODE_OUTPUT_TEXT // text emojis val code = specAndSdk.first().toIntOrNull(16) ?: return specAndSdk.first() to KeyCode.MULTIPLE_CODE_POINTS // text emojis
val label = StringUtils.newSingleCodePointString(code) val label = StringUtils.newSingleCodePointString(code)
return label to code return label to code
} }
@ -75,7 +76,7 @@ class EmojiParser(private val params: KeyboardParams, private val context: Conte
val cp = codePointString.toInt(16) val cp = codePointString.toInt(16)
labelBuilder.appendCodePoint(cp) labelBuilder.appendCodePoint(cp)
} }
return labelBuilder.toString() to Constants.CODE_OUTPUT_TEXT return labelBuilder.toString() to KeyCode.MULTIPLE_CODE_POINTS
} }
private fun parseEmojiKey(spec: String, popupKeysString: String? = null): KeyParams? { private fun parseEmojiKey(spec: String, popupKeysString: String? = null): KeyParams? {

View file

@ -11,6 +11,7 @@ import helium314.keyboard.keyboard.internal.keyboard_parser.floris.AutoTextKeyDa
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.CaseSelector import helium314.keyboard.keyboard.internal.keyboard_parser.floris.CaseSelector
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.CharWidthSelector import helium314.keyboard.keyboard.internal.keyboard_parser.floris.CharWidthSelector
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KanaSelector import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KanaSelector
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode.convertFloris
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyData import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyData
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.LayoutDirectionSelector import helium314.keyboard.keyboard.internal.keyboard_parser.floris.LayoutDirectionSelector
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.MultiTextKeyData import helium314.keyboard.keyboard.internal.keyboard_parser.floris.MultiTextKeyData
@ -34,7 +35,7 @@ class JsonKeyboardParser(private val params: KeyboardParams, private val context
// initially 200 ms parse (debug build on S4 mini) // initially 200 ms parse (debug build on S4 mini)
// after a few parses it's optimized and 20-30 ms // after a few parses it's optimized and 20-30 ms
// whole load is 50-70 ms vs 30-55 with simple parser -> it's ok // whole load is 50-70 ms vs 30-55 with simple parser -> it's ok
return florisKeyData.mapTo(mutableListOf()) { it.mapNotNull { it.compute(params) } } return florisKeyData.mapTo(mutableListOf()) { it.mapNotNull { it.compute(params)?.convertFloris() } }
} }
} }

View file

@ -12,6 +12,7 @@ import helium314.keyboard.keyboard.KeyboardId
import helium314.keyboard.keyboard.KeyboardTheme import helium314.keyboard.keyboard.KeyboardTheme
import helium314.keyboard.keyboard.internal.KeyboardIconsSet import helium314.keyboard.keyboard.internal.KeyboardIconsSet
import helium314.keyboard.keyboard.internal.KeyboardParams import helium314.keyboard.keyboard.internal.KeyboardParams
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyData import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyData
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyType import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyType
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.SimplePopups import helium314.keyboard.keyboard.internal.keyboard_parser.floris.SimplePopups
@ -415,7 +416,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
return when (key) { return when (key) {
FunctionalKey.SYMBOL_ALPHA -> KeyParams( FunctionalKey.SYMBOL_ALPHA -> KeyParams(
if (params.mId.isAlphabetKeyboard) getToSymbolLabel() else params.mLocaleKeyboardInfos.labelAlphabet, if (params.mId.isAlphabetKeyboard) getToSymbolLabel() else params.mLocaleKeyboardInfos.labelAlphabet,
Constants.CODE_SWITCH_ALPHA_SYMBOL, KeyCode.ALPHA_SYMBOL,
params, params,
width, width,
Key.LABEL_FLAGS_PRESERVE_CASE or Key.LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR, Key.LABEL_FLAGS_PRESERVE_CASE or Key.LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR,
@ -424,7 +425,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
) )
FunctionalKey.SYMBOL -> KeyParams( FunctionalKey.SYMBOL -> KeyParams(
getToSymbolLabel(), getToSymbolLabel(),
Constants.CODE_SWITCH_SYMBOL, KeyCode.SYMBOL,
params, params,
width, width,
Key.LABEL_FLAGS_PRESERVE_CASE or Key.LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR, Key.LABEL_FLAGS_PRESERVE_CASE or Key.LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR,
@ -433,7 +434,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
) )
FunctionalKey.ALPHA -> KeyParams( FunctionalKey.ALPHA -> KeyParams(
params.mLocaleKeyboardInfos.labelAlphabet, params.mLocaleKeyboardInfos.labelAlphabet,
Constants.CODE_SWITCH_ALPHA, KeyCode.ALPHA,
params, params,
width, width,
Key.LABEL_FLAGS_PRESERVE_CASE or Key.LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR, Key.LABEL_FLAGS_PRESERVE_CASE or Key.LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR,

View file

@ -324,8 +324,8 @@ private val euro = "€" to arrayOf("£", "¥", "$", "¢", "₱")
private val dram = "֏" to arrayOf("", "", "$", "£", "¥") private val dram = "֏" to arrayOf("", "", "$", "£", "¥")
private val rupee = "" to arrayOf("£", "", "$", "¢", "¥", "") private val rupee = "" to arrayOf("£", "", "$", "¢", "¥", "")
private val pound = "£" to arrayOf("", "¥", "$", "¢", "") private val pound = "£" to arrayOf("", "¥", "$", "¢", "")
private val ruble = "" to arrayOf("", "$", "£", "¥") private val ruble = "" to arrayOf("", "$", "£", "¥", "")
private val lira = "" to arrayOf("", "$", "£", "¥") private val lira = "" to arrayOf("", "$", "£", "¥", "")
private val dollar = "$" to arrayOf("£", "¢", "", "¥", "") private val dollar = "$" to arrayOf("£", "¢", "", "¥", "")
private val euroCountries = "AD|AT|BE|BG|HR|CY|CZ|DA|EE|FI|FR|DE|GR|HU|IE|IT|XK|LV|LT|LU|MT|MO|ME|NL|PL|PT|RO|SM|SK|SI|ES|VA".toRegex() private val euroCountries = "AD|AT|BE|BG|HR|CY|CZ|DA|EE|FI|FR|DE|GR|HU|IE|IT|XK|LV|LT|LU|MT|MO|ME|NL|PL|PT|RO|SM|SK|SI|ES|VA".toRegex()
private val euroLocales = "bg|ca|cs|da|de|el|en|es|et|eu|fi|fr|ga|gl|hr|hu|it|lb|lt|lv|mt|nl|pl|pt|ro|sk|sl|sq|sr|sv".toRegex() private val euroLocales = "bg|ca|cs|da|de|el|en|es|et|eu|fi|fr|ga|gl|hr|hu|it|lb|lt|lv|mt|nl|pl|pt|ro|sk|sl|sq|sr|sv".toRegex()

View file

@ -5,28 +5,21 @@
*/ */
package helium314.keyboard.keyboard.internal.keyboard_parser.floris package helium314.keyboard.keyboard.internal.keyboard_parser.floris
// taken from FlorisBoard, not actually used // taken from FlorisBoard and modified
object KeyCode { object KeyCode {
object Spec { object Spec {
const val CHARACTERS_MIN = 1 const val CHARACTERS_MIN = 1
const val CHARACTERS_MAX = 65535 const val CHARACTERS_MAX = 65535
val CHARACTERS = CHARACTERS_MIN..CHARACTERS_MAX val CHARACTERS = CHARACTERS_MIN..CHARACTERS_MAX
const val INTERNAL_MIN = -9999 const val INTERNAL_FLORIS_MIN = -9999
const val INTERNAL_MAX = -1 const val INTERNAL_FLORIS_MAX = -1
val INTERNAL = INTERNAL_MIN..INTERNAL_MAX val INTERNAL_FLORIS = INTERNAL_FLORIS_MIN..INTERNAL_FLORIS_MAX
val INTERNAL_HELI = -19999..-10000 // for keys exclusive to this app
} }
const val UNSPECIFIED = 0 const val UNSPECIFIED = 0
const val PHONE_WAIT = 59 // ;
const val PHONE_PAUSE = 44 // ,
const val SPACE = 32
const val ESCAPE = 27
const val ENTER = 10
const val TAB = 9
const val CTRL = -1 const val CTRL = -1
const val CTRL_LOCK = -2 const val CTRL_LOCK = -2
const val ALT = -3 const val ALT = -3
@ -52,7 +45,7 @@ object KeyCode {
const val CLIPBOARD_COPY = -31 const val CLIPBOARD_COPY = -31
const val CLIPBOARD_CUT = -32 const val CLIPBOARD_CUT = -32
const val CLIPBOARD_PASTE = -33 const val CLIPBOARD_PASTE = -33
const val CLIPBOARD_SELECT = -34 const val CLIPBOARD_SELECT_WORD = -34 // CLIPBOARD_SELECT
const val CLIPBOARD_SELECT_ALL = -35 const val CLIPBOARD_SELECT_ALL = -35
const val CLIPBOARD_CLEAR_HISTORY = -36 const val CLIPBOARD_CLEAR_HISTORY = -36
const val CLIPBOARD_CLEAR_FULL_HISTORY = -37 const val CLIPBOARD_CLEAR_FULL_HISTORY = -37
@ -66,17 +59,17 @@ object KeyCode {
const val UNDO = -131 const val UNDO = -131
const val REDO = -132 const val REDO = -132
const val VIEW_CHARACTERS = -201 const val ALPHA = -201 // VIEW_CHARACTERS
const val VIEW_SYMBOLS = -202 const val SYMBOL = -202 // VIEW_SYMBOLS
const val VIEW_SYMBOLS2 = -203 const val VIEW_SYMBOLS2 = -203
const val VIEW_NUMERIC = -204 const val VIEW_NUMERIC = -204
const val VIEW_NUMERIC_ADVANCED = -205 const val NUMPAD = -205 // VIEW_NUMERIC_ADVANCED
const val VIEW_PHONE = -206 const val VIEW_PHONE = -206
const val VIEW_PHONE2 = -207 const val VIEW_PHONE2 = -207
const val IME_UI_MODE_TEXT = -211 const val IME_UI_MODE_TEXT = -211
const val IME_UI_MODE_MEDIA = -212 const val EMOJI = -212 // IME_UI_MODE_MEDIA
const val IME_UI_MODE_CLIPBOARD = -213 const val CLIPBOARD = -213 // IME_UI_MODE_CLIPBOARD
const val SYSTEM_INPUT_METHOD_PICKER = -221 const val SYSTEM_INPUT_METHOD_PICKER = -221
const val SYSTEM_PREV_INPUT_METHOD = -222 const val SYSTEM_PREV_INPUT_METHOD = -222
@ -125,4 +118,63 @@ object KeyCode {
const val HALF_SPACE = 8204 const val HALF_SPACE = 8204
const val CJK_SPACE = 12288 const val CJK_SPACE = 12288
// heliboard only codes
const val ALPHA_SYMBOL = -10001
const val START_ONE_HANDED_MODE = -10002
const val STOP_ONE_HANDED_MODE = -10003
const val SWITCH_ONE_HANDED_MODE = -10004
const val SHIFT_ENTER = -10005
const val ACTION_NEXT = -10006
const val ACTION_PREVIOUS = -10007
const val SYMBOL_SHIFT = -10008 // todo: check, maybe can be removed
// Code value representing the code is not specified.
const val NOT_SPECIFIED = -10009 // todo: not sure if there is need to have the "old" unspecified keyCode different, just test it and maybe merge
/** to make sure a FlorisBoard code works when reading a JSON layout */
private fun Int.checkOrConvertCode(): Int = when (this) {
// todo: should work, but not yet
// CURRENCY_SLOT_1, CURRENCY_SLOT_2, CURRENCY_SLOT_3, CURRENCY_SLOT_4, CURRENCY_SLOT_5, CURRENCY_SLOT_6,
// working
VOICE_INPUT, LANGUAGE_SWITCH, SETTINGS, DELETE, ALPHA, SYMBOL, EMOJI, CLIPBOARD,
UNDO, REDO, ARROW_DOWN, ARROW_UP, ARROW_RIGHT, ARROW_LEFT, CLIPBOARD_COPY, CLIPBOARD_SELECT_ALL,
CLIPBOARD_SELECT_WORD, TOGGLE_INCOGNITO_MODE, TOGGLE_AUTOCORRECT, MOVE_START_OF_LINE, MOVE_END_OF_LINE,
SHIFT, CAPS_LOCK, MULTIPLE_CODE_POINTS, UNSPECIFIED,
// heliboard only
ALPHA_SYMBOL, START_ONE_HANDED_MODE, STOP_ONE_HANDED_MODE, SWITCH_ONE_HANDED_MODE, SHIFT_ENTER,
ACTION_NEXT, ACTION_PREVIOUS, SYMBOL_SHIFT, NOT_SPECIFIED
-> this
// conversion
IME_UI_MODE_TEXT -> ALPHA
else -> throw IllegalStateException("key code $this not yet supported")
}
/** to make sure a FlorisBoard label works when reading a JSON layout */
private fun String.convertFlorisLabel(): String = when (this) {
"view_characters" -> "alpha"
"view_symbols" -> "symbol"
"view_numeric_advanced" -> "numpad"
"view_phone" -> "alpha"
"view_phone2" -> "symbols"
"ime_ui_mode_media" -> "emoji"
"ime_ui_mode_clipboard" -> "clipboard"
"ime_ui_mode_text" -> "alpha"
"currency_slot_1" -> "$$$"
"currency_slot_2" -> "$$$1"
"currency_slot_3" -> "$$$2"
"currency_slot_4" -> "$$$3"
"currency_slot_5" -> "$$$4"
"currency_slot_6" -> "$$$5"
else -> this
}
fun KeyData.convertFloris() = when (this) {
is TextKeyData -> { TextKeyData(type, code.checkOrConvertCode(), label.convertFlorisLabel(), groupId, popup, labelFlags) }
is AutoTextKeyData -> { AutoTextKeyData(type, code.checkOrConvertCode(), label.convertFlorisLabel(), groupId, popup, labelFlags) }
is MultiTextKeyData -> { MultiTextKeyData(type, codePoints, label.convertFlorisLabel(), groupId, popup, labelFlags) }
}
} }

View file

@ -7,11 +7,8 @@ package helium314.keyboard.keyboard.internal.keyboard_parser.floris
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import helium314.keyboard.keyboard.Key
import helium314.keyboard.keyboard.Key.KeyParams
import helium314.keyboard.keyboard.KeyboardId import helium314.keyboard.keyboard.KeyboardId
import helium314.keyboard.keyboard.internal.KeyboardParams import helium314.keyboard.keyboard.internal.KeyboardParams
import helium314.keyboard.keyboard.internal.keyboard_parser.rtlLabel
import helium314.keyboard.latin.common.StringUtils import helium314.keyboard.latin.common.StringUtils
// taken from FlorisBoard, small modifications // taken from FlorisBoard, small modifications
@ -58,99 +55,6 @@ interface AbstractKeyData {
} }
} }
/**
* Interface describing a basic key which can carry a character, an emoji, a special function etc. while being as
* abstract as possible.
*
* @property type The type of the key.
* @property code The Unicode code point of this key, or a special code from [KeyCode].
* @property label The label of the key. This should always be a representative string for [code].
* @property groupId The group which this key belongs to (currently only allows [GROUP_DEFAULT]).
* @property popup The popups for ths key. Can also dynamically be provided via popup extensions.
*/
interface KeyData : AbstractKeyData {
val type: KeyType
val code: Int
val label: String
val groupId: Int
val popup: PopupSet<AbstractKeyData> // not nullable because can't add number otherwise
val labelFlags: Int
// groups (currently) not supported
companion object {
/**
* Constant for the default group. If not otherwise specified, any key is automatically
* assigned to this group.
*/
const val GROUP_DEFAULT: Int = 0
/**
* Constant for the Left modifier key group. Any key belonging to this group will get the
* popups specified for "~left" in the popup mapping.
*/
const val GROUP_LEFT: Int = 1
/**
* Constant for the right modifier key group. Any key belonging to this group will get the
* popups specified for "~right" in the popup mapping.
*/
const val GROUP_RIGHT: Int = 2
/**
* Constant for the enter modifier key group. Any key belonging to this group will get the
* popups specified for "~enter" in the popup mapping.
*/
const val GROUP_ENTER: Int = 3
/**
* Constant for the enter modifier key group. Any key belonging to this group will get the
* popups specified for "~kana" in the popup mapping.
*/
const val GROUP_KANA: Int = 97
}
// make it non-nullable for simplicity, and to reflect current implementations
override fun compute(params: KeyboardParams): KeyData
fun isSpaceKey(): Boolean {
return type == KeyType.CHARACTER && (code == KeyCode.SPACE || code == KeyCode.CJK_SPACE
|| code == KeyCode.HALF_SPACE || code == KeyCode.KESHIDA)
}
fun toKeyParams(params: KeyboardParams, width: Float = params.mDefaultRelativeKeyWidth, additionalLabelFlags: Int = 0): KeyParams {
// numeric keys are assigned a higher width in number layouts
require(type == KeyType.CHARACTER || type == KeyType.NUMERIC) { "only KeyType CHARACTER or NUMERIC is supported" }
// allow GROUP_ENTER negative codes so original florisboard number layouts can be used, bu actually it's ignored
require(groupId == GROUP_DEFAULT || groupId == GROUP_ENTER) { "currently only GROUP_DEFAULT or GROUP_ENTER is supported" }
// allow some negative codes so original florisboard number layouts can be used, those codes are actually ignored
require(code >= 0 || code == -7 || code == -201 || code == -202) { "functional code $code not (yet) supported" }
require(code != KeyCode.UNSPECIFIED || label.isNotEmpty()) { "key has no code and no label" }
return if (code == KeyCode.UNSPECIFIED || code == KeyCode.MULTIPLE_CODE_POINTS) {
// code will be determined from label if possible (i.e. label is single code point)
// but also longer labels should work without issues, also for MultiTextKeyData
KeyParams(
label.rtlLabel(params), // todo (when supported): convert special labels to keySpec
params,
width,
labelFlags or additionalLabelFlags,
Key.BACKGROUND_TYPE_NORMAL, // todo (when supported): determine type
popup,
)
} else {
KeyParams(
label.ifEmpty { StringUtils.newSingleCodePointString(code) },
code, // todo (when supported): convert codes < 0, because florisboard layouts should still be usable
params,
width,
labelFlags or additionalLabelFlags,
Key.BACKGROUND_TYPE_NORMAL,
popup,
)
}
}
}
/** /**
* Allows to select an [AbstractKeyData] based on the current caps state. Note that this type of selector only really * Allows to select an [AbstractKeyData] based on the current caps state. Note that this type of selector only really
* makes sense in a text context, though technically speaking it can be used anywhere, so this implementation allows * makes sense in a text context, though technically speaking it can be used anywhere, so this implementation allows

View file

@ -10,11 +10,107 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient import kotlinx.serialization.Transient
import helium314.keyboard.keyboard.Key import helium314.keyboard.keyboard.Key
import helium314.keyboard.keyboard.internal.KeyboardParams import helium314.keyboard.keyboard.internal.KeyboardParams
import helium314.keyboard.keyboard.internal.keyboard_parser.rtlLabel
import helium314.keyboard.latin.common.Constants
import helium314.keyboard.latin.common.StringUtils
// taken from FlorisBoard, small modifications (see also KeyData) // taken from FlorisBoard, small modifications (see also KeyData)
// internal keys removed (currently no plan to support them) // internal keys removed (currently no plan to support them)
// added String.toTextKey // added String.toTextKey
// currency key handling (see todo below...) // currency key handling (see todo below...)
/**
* Interface describing a basic key which can carry a character, an emoji, a special function etc. while being as
* abstract as possible.
*
* @property type The type of the key.
* @property code The Unicode code point of this key, or a special code from [KeyCode].
* @property label The label of the key. This should always be a representative string for [code].
* @property groupId The group which this key belongs to (currently only allows [GROUP_DEFAULT]).
* @property popup The popups for ths key. Can also dynamically be provided via popup extensions.
*/
sealed interface KeyData : AbstractKeyData {
val type: KeyType
val code: Int
val label: String
val groupId: Int
val popup: PopupSet<AbstractKeyData> // not nullable because can't add number otherwise
val labelFlags: Int
// groups (currently) not supported
companion object {
/**
* Constant for the default group. If not otherwise specified, any key is automatically
* assigned to this group.
*/
const val GROUP_DEFAULT: Int = 0
/**
* Constant for the Left modifier key group. Any key belonging to this group will get the
* popups specified for "~left" in the popup mapping.
*/
const val GROUP_LEFT: Int = 1
/**
* Constant for the right modifier key group. Any key belonging to this group will get the
* popups specified for "~right" in the popup mapping.
*/
const val GROUP_RIGHT: Int = 2
/**
* Constant for the enter modifier key group. Any key belonging to this group will get the
* popups specified for "~enter" in the popup mapping.
*/
const val GROUP_ENTER: Int = 3
/**
* Constant for the enter modifier key group. Any key belonging to this group will get the
* popups specified for "~kana" in the popup mapping.
*/
const val GROUP_KANA: Int = 97
}
// make it non-nullable for simplicity, and to reflect current implementations
override fun compute(params: KeyboardParams): KeyData
fun isSpaceKey(): Boolean {
return type == KeyType.CHARACTER && (code == Constants.CODE_SPACE || code == KeyCode.CJK_SPACE
|| code == KeyCode.HALF_SPACE || code == KeyCode.KESHIDA)
}
fun toKeyParams(params: KeyboardParams, width: Float = params.mDefaultRelativeKeyWidth, additionalLabelFlags: Int = 0): Key.KeyParams {
// todo: remove checks here, do only when reading json layouts
// numeric keys are assigned a higher width in number layouts
require(type == KeyType.CHARACTER || type == KeyType.NUMERIC) { "only KeyType CHARACTER or NUMERIC is supported" }
// allow GROUP_ENTER negative codes so original florisboard number layouts can be used, bu actually it's ignored
require(groupId == GROUP_DEFAULT || groupId == GROUP_ENTER) { "currently only GROUP_DEFAULT or GROUP_ENTER is supported" }
require(code != KeyCode.UNSPECIFIED || label.isNotEmpty()) { "key has no code and no label" }
return if (code == KeyCode.UNSPECIFIED || code == KeyCode.MULTIPLE_CODE_POINTS) {
// code will be determined from label if possible (i.e. label is single code point)
// but also longer labels should work without issues, also for MultiTextKeyData
Key.KeyParams(
label.rtlLabel(params), // todo (when supported): convert special labels to keySpec
params,
width,
labelFlags or additionalLabelFlags,
Key.BACKGROUND_TYPE_NORMAL, // todo (when supported): determine type
popup,
)
} else {
Key.KeyParams(
label.ifEmpty { StringUtils.newSingleCodePointString(code) },
code,
params,
width,
labelFlags or additionalLabelFlags,
Key.BACKGROUND_TYPE_NORMAL,
popup,
)
}
}
}
/** /**
* Data class which describes a single key and its attributes. * Data class which describes a single key and its attributes.
* *
@ -47,7 +143,7 @@ class TextKeyData(
return params.mLocaleKeyboardInfos.currencyKey return params.mLocaleKeyboardInfos.currencyKey
.let { it.first.toTextKey(it.second.toList(), labelFlags = Key.LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO) } // the flag is to match old parser, but why for main currency key, but not for others? .let { it.first.toTextKey(it.second.toList(), labelFlags = Key.LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO) } // the flag is to match old parser, but why for main currency key, but not for others?
val n = label.substringAfter("$$$").toIntOrNull() val n = label.substringAfter("$$$").toIntOrNull()
if (n != null && n <= 4 && n > 0) if (n != null && n <= 5 && n > 0)
return params.mLocaleKeyboardInfos.currencyKey.second[n - 1].toTextKey() return params.mLocaleKeyboardInfos.currencyKey.second[n - 1].toTextKey()
} }
return this return this
@ -55,7 +151,7 @@ class TextKeyData(
override fun asString(isForDisplay: Boolean): String { override fun asString(isForDisplay: Boolean): String {
return buildString { return buildString {
if (isForDisplay || code == KeyCode.URI_COMPONENT_TLD || code < KeyCode.SPACE) { if (isForDisplay || code == KeyCode.URI_COMPONENT_TLD || code < Constants.CODE_SPACE) {
if (Unicode.isNonSpacingMark(code) && !label.startsWith("")) { if (Unicode.isNonSpacingMark(code) && !label.startsWith("")) {
append("") append("")
} }
@ -95,7 +191,7 @@ class AutoTextKeyData(
override fun asString(isForDisplay: Boolean): String { override fun asString(isForDisplay: Boolean): String {
return buildString { return buildString {
if (isForDisplay || code == KeyCode.URI_COMPONENT_TLD || code < KeyCode.SPACE) { if (isForDisplay || code == KeyCode.URI_COMPONENT_TLD || code < Constants.CODE_SPACE) {
if (Unicode.isNonSpacingMark(code) && !label.startsWith("")) { if (Unicode.isNonSpacingMark(code) && !label.startsWith("")) {
append("") append("")
} }

View file

@ -12,6 +12,7 @@ import android.os.Vibrator;
import android.view.HapticFeedbackConstants; import android.view.HapticFeedbackConstants;
import android.view.View; import android.view.View;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.common.Constants; import helium314.keyboard.latin.common.Constants;
import helium314.keyboard.latin.settings.SettingsValues; import helium314.keyboard.latin.settings.SettingsValues;
@ -82,7 +83,7 @@ public final class AudioAndHapticFeedbackManager {
} }
final int sound; final int sound;
switch (code) { switch (code) {
case Constants.CODE_DELETE: case KeyCode.DELETE:
sound = AudioManager.FX_KEYPRESS_DELETE; sound = AudioManager.FX_KEYPRESS_DELETE;
break; break;
case Constants.CODE_ENTER: case Constants.CODE_ENTER:

View file

@ -13,6 +13,7 @@ import android.widget.FrameLayout
import android.widget.ImageButton import android.widget.ImageButton
import helium314.keyboard.keyboard.KeyboardActionListener import helium314.keyboard.keyboard.KeyboardActionListener
import helium314.keyboard.keyboard.KeyboardSwitcher import helium314.keyboard.keyboard.KeyboardSwitcher
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
import helium314.keyboard.latin.common.ColorType import helium314.keyboard.latin.common.ColorType
import helium314.keyboard.latin.common.Constants import helium314.keyboard.latin.common.Constants
import helium314.keyboard.latin.settings.Settings import helium314.keyboard.latin.settings.Settings
@ -83,7 +84,7 @@ class KeyboardWrapperView @JvmOverloads constructor(
if (newScale == oldScale) return@setOnTouchListener true if (newScale == oldScale) return@setOnTouchListener true
Settings.getInstance().writeOneHandedModeScale(newScale) Settings.getInstance().writeOneHandedModeScale(newScale)
oneHandedModeEnabled = false // intentionally putting wrong value, so KeyboardSwitcher.setOneHandedModeEnabled does actually reload oneHandedModeEnabled = false // intentionally putting wrong value, so KeyboardSwitcher.setOneHandedModeEnabled does actually reload
keyboardActionListener?.onCodeInput(Constants.CODE_START_ONE_HANDED_MODE, keyboardActionListener?.onCodeInput(KeyCode.START_ONE_HANDED_MODE,
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false) Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false)
} }
else -> x = 0f else -> x = 0f
@ -118,11 +119,11 @@ class KeyboardWrapperView @JvmOverloads constructor(
override fun onClick(view: View) { override fun onClick(view: View) {
if (view === stopOneHandedModeBtn) { if (view === stopOneHandedModeBtn) {
keyboardActionListener?.onCodeInput(Constants.CODE_STOP_ONE_HANDED_MODE, keyboardActionListener?.onCodeInput(KeyCode.STOP_ONE_HANDED_MODE,
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE,
false /* isKeyRepeat */) false /* isKeyRepeat */)
} else if (view === switchOneHandedModeBtn) { } else if (view === switchOneHandedModeBtn) {
keyboardActionListener?.onCodeInput(Constants.CODE_SWITCH_ONE_HANDED_MODE, keyboardActionListener?.onCodeInput(KeyCode.SWITCH_ONE_HANDED_MODE,
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE,
false /* isKeyRepeat */) false /* isKeyRepeat */)
} }

View file

@ -42,6 +42,7 @@ import android.view.inputmethod.InputMethodSubtype;
import helium314.keyboard.accessibility.AccessibilityUtils; import helium314.keyboard.accessibility.AccessibilityUtils;
import helium314.keyboard.compat.ConfigurationCompatKt; import helium314.keyboard.compat.ConfigurationCompatKt;
import helium314.keyboard.compat.EditorInfoCompatUtils; import helium314.keyboard.compat.EditorInfoCompatUtils;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.common.InsetsOutlineProvider; import helium314.keyboard.latin.common.InsetsOutlineProvider;
import helium314.keyboard.dictionarypack.DictionaryPackConstants; import helium314.keyboard.dictionarypack.DictionaryPackConstants;
import helium314.keyboard.event.Event; import helium314.keyboard.event.Event;
@ -1402,7 +1403,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// some apps don't return any text via input connection, and the cursor can't be moved // some apps don't return any text via input connection, and the cursor can't be moved
// we fall back to virtually pressing the left/right key one or more times instead // we fall back to virtually pressing the left/right key one or more times instead
while (steps != 0) { while (steps != 0) {
onCodeInput(Constants.CODE_LEFT, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false); onCodeInput(KeyCode.ARROW_LEFT, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false);
++steps; ++steps;
} }
return; return;
@ -1412,7 +1413,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
moveSteps = Math.min(availableCharacters, steps); moveSteps = Math.min(availableCharacters, steps);
if (moveSteps == 0) { if (moveSteps == 0) {
while (steps != 0) { while (steps != 0) {
onCodeInput(Constants.CODE_RIGHT, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false); onCodeInput(KeyCode.ARROW_RIGHT, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false);
--steps; --steps;
} }
return; return;
@ -1446,7 +1447,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void onUpWithDeletePointerActive() { public void onUpWithDeletePointerActive() {
if (mInputLogic.mConnection.hasSelection()) { if (mInputLogic.mConnection.hasSelection()) {
mInputLogic.finishInput(); mInputLogic.finishInput();
onCodeInput(Constants.CODE_DELETE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false); onCodeInput(KeyCode.DELETE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false);
} }
} }
@ -1527,12 +1528,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// TODO: Instead of checking for alphabetic keyboard here, separate keycodes for // TODO: Instead of checking for alphabetic keyboard here, separate keycodes for
// alphabetic shift and shift while in symbol layout and get rid of this method. // alphabetic shift and shift while in symbol layout and get rid of this method.
private int getCodePointForKeyboard(final int codePoint) { private int getCodePointForKeyboard(final int codePoint) {
if (Constants.CODE_SHIFT == codePoint) { if (KeyCode.SHIFT == codePoint) {
final Keyboard currentKeyboard = mKeyboardSwitcher.getKeyboard(); final Keyboard currentKeyboard = mKeyboardSwitcher.getKeyboard();
if (null != currentKeyboard && currentKeyboard.mId.isAlphabetKeyboard()) { if (null != currentKeyboard && currentKeyboard.mId.isAlphabetKeyboard()) {
return codePoint; return codePoint;
} }
return Constants.CODE_SYMBOL_SHIFT; return KeyCode.SYMBOL_SHIFT;
} }
return codePoint; return codePoint;
} }
@ -1542,8 +1543,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void onCodeInput(final int codePoint, final int x, final int y, final boolean isKeyRepeat) { public void onCodeInput(final int codePoint, final int x, final int y, final boolean isKeyRepeat) {
if (codePoint < 0) { if (codePoint < 0) {
switch (codePoint) { switch (codePoint) {
case Constants.CODE_TOGGLE_AUTOCORRECT -> {mSettings.toggleAutoCorrect(); return; } case KeyCode.TOGGLE_AUTOCORRECT -> {mSettings.toggleAutoCorrect(); return; }
case Constants.CODE_TOGGLE_INCOGNITO -> {mSettings.toggleAlwaysIncognitoMode(); return; } case KeyCode.TOGGLE_INCOGNITO_MODE -> {mSettings.toggleAlwaysIncognitoMode(); return; }
} }
} }
// TODO: this processing does not belong inside LatinIME, the caller should be doing this. // TODO: this processing does not belong inside LatinIME, the caller should be doing this.
@ -1562,7 +1563,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// This method is public for testability of LatinIME, but also in the future it should // This method is public for testability of LatinIME, but also in the future it should
// completely replace #onCodeInput. // completely replace #onCodeInput.
public void onEvent(@NonNull final Event event) { public void onEvent(@NonNull final Event event) {
if (Constants.CODE_SHORTCUT == event.getMKeyCode()) { if (KeyCode.VOICE_INPUT == event.getMKeyCode()) {
mRichImm.switchToShortcutIme(this); mRichImm.switchToShortcutIme(this);
} }
final InputTransaction completeInputTransaction = final InputTransaction completeInputTransaction =
@ -1595,7 +1596,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override @Override
public void onTextInput(final String rawText) { public void onTextInput(final String rawText) {
// TODO: have the keyboard pass the correct key code when we need it. // TODO: have the keyboard pass the correct key code when we need it.
final Event event = Event.createSoftwareTextEvent(rawText, Constants.CODE_OUTPUT_TEXT); final Event event = Event.createSoftwareTextEvent(rawText, KeyCode.MULTIPLE_CODE_POINTS);
final InputTransaction completeInputTransaction = final InputTransaction completeInputTransaction =
mInputLogic.onTextInput(mSettings.getCurrent(), event, mInputLogic.onTextInput(mSettings.getCurrent(), event,
mKeyboardSwitcher.getKeyboardShiftMode(), mHandler); mKeyboardSwitcher.getKeyboardShiftMode(), mHandler);
@ -1802,7 +1803,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return; return;
} }
if (repeatCount > 0) { if (repeatCount > 0) {
if (code == Constants.CODE_DELETE && !mInputLogic.mConnection.canDeleteCharacters()) { if (code == KeyCode.DELETE && !mInputLogic.mConnection.canDeleteCharacters()) {
// No need to feedback when repeat delete key will have no effect. // No need to feedback when repeat delete key will have no effect.
return; return;
} }

View file

@ -9,6 +9,7 @@ package helium314.keyboard.latin;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import helium314.keyboard.keyboard.internal.KeySpecParser; import helium314.keyboard.keyboard.internal.KeySpecParser;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.common.Constants; import helium314.keyboard.latin.common.Constants;
import helium314.keyboard.latin.common.StringUtils; import helium314.keyboard.latin.common.StringUtils;
@ -62,7 +63,7 @@ public final class PunctuationSuggestions extends SuggestedWords {
public String getWord(final int index) { public String getWord(final int index) {
final String keySpec = super.getWord(index); final String keySpec = super.getWord(index);
final int code = KeySpecParser.getCode(keySpec); final int code = KeySpecParser.getCode(keySpec);
return (code == Constants.CODE_OUTPUT_TEXT) return (code == KeyCode.MULTIPLE_CODE_POINTS)
? KeySpecParser.getOutputText(keySpec) ? KeySpecParser.getOutputText(keySpec)
: StringUtils.newSingleCodePointString(code); : StringUtils.newSingleCodePointString(code);
} }

View file

@ -12,6 +12,7 @@ import helium314.keyboard.event.CombinerChain;
import helium314.keyboard.event.Event; import helium314.keyboard.event.Event;
import helium314.keyboard.keyboard.Keyboard; import helium314.keyboard.keyboard.Keyboard;
import helium314.keyboard.keyboard.KeyboardSwitcher; import helium314.keyboard.keyboard.KeyboardSwitcher;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.SuggestedWords.SuggestedWordInfo; import helium314.keyboard.latin.SuggestedWords.SuggestedWordInfo;
import helium314.keyboard.latin.common.ComposedData; import helium314.keyboard.latin.common.ComposedData;
import helium314.keyboard.latin.common.Constants; import helium314.keyboard.latin.common.Constants;
@ -176,7 +177,7 @@ public final class WordComposer {
applyProcessedEvent(event, false); applyProcessedEvent(event, false);
} }
// specifically for that Constants.CODE_OUTPUT_TEXT Hangul event: try keeping cursor position // specifically for that KeyCode.MULTIPLE_CODE_POINTS Hangul event: try keeping cursor position
// because typically nothing changes, todo: if really nothing changes maybe there is a better way to do it // because typically nothing changes, todo: if really nothing changes maybe there is a better way to do it
public void applyProcessedEvent(final Event event, final boolean keepCursorPosition) { public void applyProcessedEvent(final Event event, final boolean keepCursorPosition) {
mCombinerChain.applyProcessedEvent(event); mCombinerChain.applyProcessedEvent(event);
@ -191,7 +192,7 @@ public final class WordComposer {
if (0 == mCodePointSize) { if (0 == mCodePointSize) {
mIsOnlyFirstCharCapitalized = false; mIsOnlyFirstCharCapitalized = false;
} }
if (Constants.CODE_DELETE != event.getMKeyCode()) { if (KeyCode.DELETE != event.getMKeyCode()) {
if (newIndex < MAX_WORD_LENGTH) { if (newIndex < MAX_WORD_LENGTH) {
// In the batch input mode, the {@code mInputPointers} holds batch input points and // In the batch input mode, the {@code mInputPointers} holds batch input points and
// shouldn't be overridden by the "typed key" coordinates // shouldn't be overridden by the "typed key" coordinates

View file

@ -8,6 +8,7 @@ package helium314.keyboard.latin.common;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.BuildConfig; import helium314.keyboard.latin.BuildConfig;
public final class Constants { public final class Constants {
@ -191,48 +192,6 @@ public final class Constants {
public static final String REGEXP_PERIOD = "\\."; public static final String REGEXP_PERIOD = "\\.";
public static final String STRING_SPACE = " "; public static final String STRING_SPACE = " ";
/**
* Special keys code. Must be negative.
* These should be aligned with constants in
* {@link helium314.keyboard.keyboard.internal.KeyboardCodesSet}.
*/
// todo: switch to using KeyCode for internal values? for FlorisBoard modifier key(code) compatibility
public static final int CODE_SHIFT = -1;
public static final int CODE_CAPSLOCK = -2;
public static final int CODE_SWITCH_ALPHA_SYMBOL = -3;
public static final int CODE_OUTPUT_TEXT = -4;
public static final int CODE_DELETE = -5;
public static final int CODE_SETTINGS = -6;
public static final int CODE_SHORTCUT = -7;
public static final int CODE_ACTION_NEXT = -8;
public static final int CODE_ACTION_PREVIOUS = -9;
public static final int CODE_LANGUAGE_SWITCH = -10;
public static final int CODE_EMOJI = -11;
public static final int CODE_CLIPBOARD = -12;
public static final int CODE_SHIFT_ENTER = -13;
public static final int CODE_SYMBOL_SHIFT = -14;
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;
public static final int CODE_SWITCH_NUMPAD = -20;
public static final int CODE_SWITCH_ALPHA = -21;
public static final int CODE_SWITCH_SYMBOL = -22;
public static final int CODE_SELECT_ALL = -23;
public static final int CODE_COPY = -24;
public static final int CODE_LEFT = -25;
public static final int CODE_RIGHT = -26;
public static final int CODE_UP = -27;
public static final int CODE_DOWN = -28;
public static final int CODE_UNDO = -29;
public static final int CODE_REDO = -30;
public static final int CODE_TOGGLE_AUTOCORRECT = -31;
public static final int CODE_TOGGLE_INCOGNITO = -32;
public static final int CODE_HOME = -33;
public static final int CODE_END = -34;
public static final int CODE_SELECT_WORD = -35;
// Code value representing the code is not specified.
public static final int CODE_UNSPECIFIED = -200;
public static boolean isLetterCode(final int code) { public static boolean isLetterCode(final int code) {
return code >= CODE_SPACE; return code >= CODE_SPACE;
} }
@ -240,29 +199,29 @@ public final class Constants {
@NonNull @NonNull
public static String printableCode(final int code) { public static String printableCode(final int code) {
switch (code) { switch (code) {
case CODE_SHIFT: return "shift"; case KeyCode.SHIFT: return "shift";
case CODE_CAPSLOCK: return "capslock"; case KeyCode.CAPS_LOCK: return "capslock";
case CODE_SWITCH_ALPHA_SYMBOL: return "alpha_symbol"; case KeyCode.ALPHA_SYMBOL: return "alpha_symbol";
case CODE_SWITCH_ALPHA: return "alpha"; case KeyCode.ALPHA: return "alpha";
case CODE_SWITCH_SYMBOL: return "symbol"; case KeyCode.SYMBOL: return "symbol";
case CODE_OUTPUT_TEXT: return "text"; case KeyCode.MULTIPLE_CODE_POINTS: return "text";
case CODE_DELETE: return "delete"; case KeyCode.DELETE: return "delete";
case CODE_SETTINGS: return "settings"; case KeyCode.SETTINGS: return "settings";
case CODE_SHORTCUT: return "shortcut"; case KeyCode.VOICE_INPUT: return "shortcut";
case CODE_ACTION_NEXT: return "actionNext"; case KeyCode.ACTION_NEXT: return "actionNext";
case CODE_ACTION_PREVIOUS: return "actionPrevious"; case KeyCode.ACTION_PREVIOUS: return "actionPrevious";
case CODE_LANGUAGE_SWITCH: return "languageSwitch"; case KeyCode.LANGUAGE_SWITCH: return "languageSwitch";
case CODE_EMOJI: return "emoji"; case KeyCode.EMOJI: return "emoji";
case CODE_CLIPBOARD: return "clipboard"; case KeyCode.CLIPBOARD: return "clipboard";
case CODE_SHIFT_ENTER: return "shiftEnter"; case KeyCode.SHIFT_ENTER: return "shiftEnter";
case CODE_UNSPECIFIED: return "unspec"; case KeyCode.NOT_SPECIFIED: return "unspec";
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 KeyCode.START_ONE_HANDED_MODE: return "startOneHandedMode";
case CODE_STOP_ONE_HANDED_MODE: return "stopOneHandedMode"; case KeyCode.STOP_ONE_HANDED_MODE: return "stopOneHandedMode";
case CODE_SWITCH_ONE_HANDED_MODE: return "switchOneHandedMode"; case KeyCode.SWITCH_ONE_HANDED_MODE: return "switchOneHandedMode";
case CODE_SWITCH_NUMPAD: return "numpad"; case KeyCode.NUMPAD: return "numpad";
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);

View file

@ -9,6 +9,7 @@ package helium314.keyboard.latin.common;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.utils.ScriptUtils; import helium314.keyboard.latin.utils.ScriptUtils;
import java.util.ArrayList; import java.util.ArrayList;
@ -586,7 +587,7 @@ public final class StringUtils {
final String label = newSingleCodePointString(code); final String label = newSingleCodePointString(code);
final String titleCaseLabel = toTitleCaseOfKeyLabel(label, locale); final String titleCaseLabel = toTitleCaseOfKeyLabel(label, locale);
return codePointCount(titleCaseLabel) == 1 return codePointCount(titleCaseLabel) == 1
? titleCaseLabel.codePointAt(0) : Constants.CODE_UNSPECIFIED; ? titleCaseLabel.codePointAt(0) : KeyCode.NOT_SPECIFIED;
} }
public static int getTrailingSingleQuotesCount(@NonNull final CharSequence charSequence) { public static int getTrailingSingleQuotesCount(@NonNull final CharSequence charSequence) {

View file

@ -25,6 +25,7 @@ import helium314.keyboard.event.HangulEventDecoder;
import helium314.keyboard.event.InputTransaction; import helium314.keyboard.event.InputTransaction;
import helium314.keyboard.keyboard.Keyboard; import helium314.keyboard.keyboard.Keyboard;
import helium314.keyboard.keyboard.KeyboardSwitcher; import helium314.keyboard.keyboard.KeyboardSwitcher;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.Dictionary; import helium314.keyboard.latin.Dictionary;
import helium314.keyboard.latin.DictionaryFacilitator; import helium314.keyboard.latin.DictionaryFacilitator;
import helium314.keyboard.latin.LastComposedWord; import helium314.keyboard.latin.LastComposedWord;
@ -450,7 +451,7 @@ public final class InputLogic {
final InputTransaction inputTransaction = new InputTransaction(settingsValues, final InputTransaction inputTransaction = new InputTransaction(settingsValues,
processedEvent, SystemClock.uptimeMillis(), mSpaceState, processedEvent, SystemClock.uptimeMillis(), mSpaceState,
getActualCapsMode(settingsValues, keyboardShiftMode)); getActualCapsMode(settingsValues, keyboardShiftMode));
if (processedEvent.getMKeyCode() != Constants.CODE_DELETE if (processedEvent.getMKeyCode() != KeyCode.DELETE
|| inputTransaction.getMTimestamp() > mLastKeyTime + Constants.LONG_PRESS_MILLISECONDS) { || inputTransaction.getMTimestamp() > mLastKeyTime + Constants.LONG_PRESS_MILLISECONDS) {
mDeleteCount = 0; mDeleteCount = 0;
} }
@ -482,17 +483,17 @@ public final class InputLogic {
// the backspace key. // the backspace key.
if (!mConnection.hasSlowInputConnection() && !mWordComposer.isComposingWord() if (!mConnection.hasSlowInputConnection() && !mWordComposer.isComposingWord()
&& (settingsValues.isWordCodePoint(processedEvent.getMCodePoint()) && (settingsValues.isWordCodePoint(processedEvent.getMCodePoint())
|| processedEvent.getMKeyCode() == Constants.CODE_DELETE) || processedEvent.getMKeyCode() == KeyCode.DELETE)
) { ) {
mWordBeingCorrectedByCursor = getWordAtCursor(settingsValues, currentKeyboardScript); mWordBeingCorrectedByCursor = getWordAtCursor(settingsValues, currentKeyboardScript);
} }
if (!inputTransaction.didAutoCorrect() && processedEvent.getMKeyCode() != Constants.CODE_SHIFT if (!inputTransaction.didAutoCorrect() && processedEvent.getMKeyCode() != KeyCode.SHIFT
&& processedEvent.getMKeyCode() != Constants.CODE_CAPSLOCK && processedEvent.getMKeyCode() != KeyCode.CAPS_LOCK
&& processedEvent.getMKeyCode() != Constants.CODE_SWITCH_ALPHA_SYMBOL && processedEvent.getMKeyCode() != KeyCode.ALPHA_SYMBOL
&& processedEvent.getMKeyCode() != Constants.CODE_SWITCH_ALPHA && processedEvent.getMKeyCode() != KeyCode.ALPHA
&& processedEvent.getMKeyCode() != Constants.CODE_SWITCH_SYMBOL) && processedEvent.getMKeyCode() != KeyCode.SYMBOL)
mLastComposedWord.deactivate(); mLastComposedWord.deactivate();
if (Constants.CODE_DELETE != processedEvent.getMKeyCode()) { if (KeyCode.DELETE != processedEvent.getMKeyCode()) {
mEnteredText = null; mEnteredText = null;
} }
mConnection.endBatchEdit(); mConnection.endBatchEdit();
@ -649,12 +650,12 @@ public final class InputLogic {
private void handleFunctionalEvent(final Event event, final InputTransaction inputTransaction, private void handleFunctionalEvent(final Event event, final InputTransaction inputTransaction,
final String currentKeyboardScript, final LatinIME.UIHandler handler) { final String currentKeyboardScript, final LatinIME.UIHandler handler) {
switch (event.getMKeyCode()) { switch (event.getMKeyCode()) {
case Constants.CODE_DELETE: case KeyCode.DELETE:
handleBackspaceEvent(event, inputTransaction, currentKeyboardScript); handleBackspaceEvent(event, inputTransaction, currentKeyboardScript);
// Backspace is a functional key, but it affects the contents of the editor. // Backspace is a functional key, but it affects the contents of the editor.
inputTransaction.setDidAffectContents(); inputTransaction.setDidAffectContents();
break; break;
case Constants.CODE_SHIFT: case KeyCode.SHIFT:
performRecapitalization(inputTransaction.getMSettingsValues()); performRecapitalization(inputTransaction.getMSettingsValues());
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW); inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
if (mSuggestedWords.isPrediction()) { if (mSuggestedWords.isPrediction()) {
@ -666,19 +667,19 @@ public final class InputLogic {
&& inputTransaction.getMSettingsValues().isUsuallyFollowedBySpace(mConnection.getCodePointBeforeCursor())) && inputTransaction.getMSettingsValues().isUsuallyFollowedBySpace(mConnection.getCodePointBeforeCursor()))
mSpaceState = SpaceState.NONE; mSpaceState = SpaceState.NONE;
break; break;
case Constants.CODE_SETTINGS: case KeyCode.SETTINGS:
onSettingsKeyPressed(); onSettingsKeyPressed();
break; break;
case Constants.CODE_ACTION_NEXT: case KeyCode.ACTION_NEXT:
performEditorAction(EditorInfo.IME_ACTION_NEXT); performEditorAction(EditorInfo.IME_ACTION_NEXT);
break; break;
case Constants.CODE_ACTION_PREVIOUS: case KeyCode.ACTION_PREVIOUS:
performEditorAction(EditorInfo.IME_ACTION_PREVIOUS); performEditorAction(EditorInfo.IME_ACTION_PREVIOUS);
break; break;
case Constants.CODE_LANGUAGE_SWITCH: case KeyCode.LANGUAGE_SWITCH:
handleLanguageSwitchKey(); handleLanguageSwitchKey();
break; break;
case Constants.CODE_CLIPBOARD: case KeyCode.CLIPBOARD:
// Note: If clipboard history is enabled, switching to clipboard keyboard // Note: If clipboard history is enabled, switching to clipboard keyboard
// is being handled in {@link KeyboardState#onEvent(Event,int)}. // is being handled in {@link KeyboardState#onEvent(Event,int)}.
// If disabled, current clipboard content is committed. // If disabled, current clipboard content is committed.
@ -691,7 +692,7 @@ public final class InputLogic {
} }
} }
break; break;
case Constants.CODE_SHIFT_ENTER: case KeyCode.SHIFT_ENTER:
final Event tmpEvent = Event.createSoftwareKeypressEvent(Constants.CODE_ENTER, final Event tmpEvent = Event.createSoftwareKeypressEvent(Constants.CODE_ENTER,
event.getMKeyCode(), event.getMX(), event.getMY(), event.isKeyRepeat()); event.getMKeyCode(), event.getMX(), event.getMY(), event.isKeyRepeat());
handleNonSpecialCharacterEvent(tmpEvent, inputTransaction, handler); handleNonSpecialCharacterEvent(tmpEvent, inputTransaction, handler);
@ -699,60 +700,60 @@ 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_OUTPUT_TEXT: case KeyCode.MULTIPLE_CODE_POINTS:
// added in the hangul branch, createEventChainFromSequence // added in the hangul branch, createEventChainFromSequence
// this introduces issues like space being added behind cursor, or input deleting // this introduces issues like space being added behind cursor, or input deleting
// a word, but the keepCursorPosition applyProcessedEvent seems to help here // a word, but the keepCursorPosition applyProcessedEvent seems to help here
mWordComposer.applyProcessedEvent(event, true); mWordComposer.applyProcessedEvent(event, true);
break; break;
case Constants.CODE_SELECT_ALL: case KeyCode.CLIPBOARD_SELECT_ALL:
mConnection.selectAll(); mConnection.selectAll();
break; break;
case Constants.CODE_SELECT_WORD: case KeyCode.CLIPBOARD_SELECT_WORD:
mConnection.selectWord(inputTransaction.getMSettingsValues().mSpacingAndPunctuations, currentKeyboardScript); mConnection.selectWord(inputTransaction.getMSettingsValues().mSpacingAndPunctuations, currentKeyboardScript);
break; break;
case Constants.CODE_COPY: case KeyCode.CLIPBOARD_COPY:
mConnection.copyText(); mConnection.copyText();
break; break;
case Constants.CODE_LEFT: case KeyCode.ARROW_LEFT:
sendDownUpKeyEvent(KeyEvent.KEYCODE_DPAD_LEFT); sendDownUpKeyEvent(KeyEvent.KEYCODE_DPAD_LEFT);
break; break;
case Constants.CODE_RIGHT: case KeyCode.ARROW_RIGHT:
sendDownUpKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT); sendDownUpKeyEvent(KeyEvent.KEYCODE_DPAD_RIGHT);
break; break;
case Constants.CODE_UP: case KeyCode.ARROW_UP:
sendDownUpKeyEvent(KeyEvent.KEYCODE_DPAD_UP); sendDownUpKeyEvent(KeyEvent.KEYCODE_DPAD_UP);
break; break;
case Constants.CODE_DOWN: case KeyCode.ARROW_DOWN:
sendDownUpKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN); sendDownUpKeyEvent(KeyEvent.KEYCODE_DPAD_DOWN);
break; break;
case Constants.CODE_UNDO: case KeyCode.UNDO:
sendDownUpKeyEventWithMetaState(KeyEvent.KEYCODE_Z, KeyEvent.META_CTRL_ON); sendDownUpKeyEventWithMetaState(KeyEvent.KEYCODE_Z, KeyEvent.META_CTRL_ON);
break; break;
case Constants.CODE_REDO: case KeyCode.REDO:
sendDownUpKeyEventWithMetaState(KeyEvent.KEYCODE_Z, KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON); sendDownUpKeyEventWithMetaState(KeyEvent.KEYCODE_Z, KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON);
break; break;
case Constants.CODE_HOME: case KeyCode.MOVE_START_OF_LINE:
sendDownUpKeyEvent(KeyEvent.KEYCODE_MOVE_HOME); sendDownUpKeyEvent(KeyEvent.KEYCODE_MOVE_HOME);
break; break;
case Constants.CODE_END: case KeyCode.MOVE_END_OF_LINE:
sendDownUpKeyEvent(KeyEvent.KEYCODE_MOVE_END); sendDownUpKeyEvent(KeyEvent.KEYCODE_MOVE_END);
break; break;
case Constants.CODE_SHORTCUT: case KeyCode.VOICE_INPUT:
// switching to shortcut IME, shift state, keyboard,... is handled by LatinIME, // switching to shortcut IME, shift state, keyboard,... is handled by LatinIME,
// {@link KeyboardSwitcher#onEvent(Event)}, or {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}. // {@link KeyboardSwitcher#onEvent(Event)}, or {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}.
// We need to switch to the shortcut IME. This is handled by LatinIME since the // We need to switch to the shortcut IME. This is handled by LatinIME since the
// input logic has no business with IME switching. // input logic has no business with IME switching.
case Constants.CODE_CAPSLOCK: case KeyCode.CAPS_LOCK:
case Constants.CODE_SYMBOL_SHIFT: case KeyCode.SYMBOL_SHIFT:
case Constants.CODE_SWITCH_ALPHA_SYMBOL: case KeyCode.ALPHA_SYMBOL:
case Constants.CODE_SWITCH_ALPHA: case KeyCode.ALPHA:
case Constants.CODE_SWITCH_SYMBOL: case KeyCode.SYMBOL:
case Constants.CODE_SWITCH_NUMPAD: case KeyCode.NUMPAD:
case Constants.CODE_EMOJI: case KeyCode.EMOJI:
case Constants.CODE_START_ONE_HANDED_MODE: case KeyCode.START_ONE_HANDED_MODE:
case Constants.CODE_STOP_ONE_HANDED_MODE: case KeyCode.STOP_ONE_HANDED_MODE:
case Constants.CODE_SWITCH_ONE_HANDED_MODE: case KeyCode.SWITCH_ONE_HANDED_MODE:
break; break;
default: default:
throw new RuntimeException("Unknown key code : " + event.getMKeyCode()); throw new RuntimeException("Unknown key code : " + event.getMKeyCode());

View file

@ -16,6 +16,7 @@ import helium314.keyboard.keyboard.Keyboard;
import helium314.keyboard.keyboard.internal.KeyboardBuilder; import helium314.keyboard.keyboard.internal.KeyboardBuilder;
import helium314.keyboard.keyboard.internal.KeyboardIconsSet; import helium314.keyboard.keyboard.internal.KeyboardIconsSet;
import helium314.keyboard.keyboard.internal.KeyboardParams; import helium314.keyboard.keyboard.internal.KeyboardParams;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.R; import helium314.keyboard.latin.R;
import helium314.keyboard.latin.SuggestedWords; import helium314.keyboard.latin.SuggestedWords;
import helium314.keyboard.latin.common.Constants; import helium314.keyboard.latin.common.Constants;
@ -230,7 +231,7 @@ public final class MoreSuggestions extends Keyboard {
public MoreSuggestionKey(final String word, final String info, final int index, public MoreSuggestionKey(final String word, final String info, final int index,
final MoreSuggestionsParam params) { final MoreSuggestionsParam params) {
super(word /* label */, KeyboardIconsSet.ICON_UNDEFINED, Constants.CODE_OUTPUT_TEXT, super(word /* label */, KeyboardIconsSet.ICON_UNDEFINED, KeyCode.MULTIPLE_CODE_POINTS,
word /* outputText */, info, 0 /* labelFlags */, Key.BACKGROUND_TYPE_NORMAL, word /* outputText */, info, 0 /* labelFlags */, Key.BACKGROUND_TYPE_NORMAL,
params.getX(index), params.getY(index), params.getWidth(index), params.getX(index), params.getY(index), params.getWidth(index),
params.mDefaultRowHeight, params.mHorizontalGap, params.mVerticalGap); params.mDefaultRowHeight, params.mHorizontalGap, params.mVerticalGap);

View file

@ -45,6 +45,7 @@ import helium314.keyboard.accessibility.AccessibilityUtils;
import helium314.keyboard.keyboard.Keyboard; import helium314.keyboard.keyboard.Keyboard;
import helium314.keyboard.keyboard.MainKeyboardView; import helium314.keyboard.keyboard.MainKeyboardView;
import helium314.keyboard.keyboard.PopupKeysPanel; import helium314.keyboard.keyboard.PopupKeysPanel;
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
import helium314.keyboard.latin.AudioAndHapticFeedbackManager; import helium314.keyboard.latin.AudioAndHapticFeedbackManager;
import helium314.keyboard.latin.Dictionary; import helium314.keyboard.latin.Dictionary;
import helium314.keyboard.latin.R; import helium314.keyboard.latin.R;
@ -645,7 +646,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
@Override @Override
public void onClick(final View view) { public void onClick(final View view) {
AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback(Constants.CODE_UNSPECIFIED, this); AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback(KeyCode.NOT_SPECIFIED, this);
final Object tag = view.getTag(); final Object tag = view.getTag();
if (tag instanceof ToolbarKey) { if (tag instanceof ToolbarKey) {
final Integer code = getCodeForToolbarKey((ToolbarKey) tag); final Integer code = getCodeForToolbarKey((ToolbarKey) tag);

View file

@ -7,8 +7,8 @@ import android.content.res.TypedArray
import android.widget.ImageButton import android.widget.ImageButton
import android.widget.ImageView import android.widget.ImageView
import androidx.core.content.edit import androidx.core.content.edit
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
import helium314.keyboard.latin.R import helium314.keyboard.latin.R
import helium314.keyboard.latin.common.Constants.*
import helium314.keyboard.latin.settings.Settings import helium314.keyboard.latin.settings.Settings
import helium314.keyboard.latin.utils.ToolbarKey.* import helium314.keyboard.latin.utils.ToolbarKey.*
@ -35,23 +35,23 @@ fun createToolbarKey(context: Context, keyboardAttr: TypedArray, key: ToolbarKey
} }
fun getCodeForToolbarKey(key: ToolbarKey) = when (key) { fun getCodeForToolbarKey(key: ToolbarKey) = when (key) {
VOICE -> CODE_SHORTCUT VOICE -> KeyCode.VOICE_INPUT
SETTINGS -> CODE_SETTINGS SETTINGS -> KeyCode.SETTINGS
CLIPBOARD -> CODE_CLIPBOARD CLIPBOARD -> KeyCode.CLIPBOARD
SELECT_ALL -> CODE_SELECT_ALL SELECT_ALL -> KeyCode.CLIPBOARD_SELECT_ALL
COPY -> CODE_COPY COPY -> KeyCode.CLIPBOARD_COPY
ONE_HANDED -> if (Settings.getInstance().current.mOneHandedModeEnabled) CODE_STOP_ONE_HANDED_MODE else CODE_START_ONE_HANDED_MODE ONE_HANDED -> if (Settings.getInstance().current.mOneHandedModeEnabled) KeyCode.STOP_ONE_HANDED_MODE else KeyCode.START_ONE_HANDED_MODE
LEFT -> CODE_LEFT LEFT -> KeyCode.ARROW_LEFT
RIGHT -> CODE_RIGHT RIGHT -> KeyCode.ARROW_RIGHT
UP -> CODE_UP UP -> KeyCode.ARROW_UP
DOWN -> CODE_DOWN DOWN -> KeyCode.ARROW_DOWN
UNDO -> CODE_UNDO UNDO -> KeyCode.UNDO
REDO -> CODE_REDO REDO -> KeyCode.REDO
INCOGNITO -> CODE_TOGGLE_INCOGNITO INCOGNITO -> KeyCode.TOGGLE_INCOGNITO_MODE
AUTOCORRECT -> CODE_TOGGLE_AUTOCORRECT AUTOCORRECT -> KeyCode.TOGGLE_AUTOCORRECT
FULL_LEFT -> CODE_HOME FULL_LEFT -> KeyCode.MOVE_START_OF_LINE
FULL_RIGHT -> CODE_END FULL_RIGHT -> KeyCode.MOVE_END_OF_LINE
SELECT_WORD -> CODE_SELECT_WORD SELECT_WORD -> KeyCode.CLIPBOARD_SELECT_WORD
CLEAR_CLIPBOARD -> null // not managed via code input CLEAR_CLIPBOARD -> null // not managed via code input
} }

View file

@ -1,6 +1,7 @@
package helium314.keyboard package helium314.keyboard
import helium314.keyboard.keyboard.internal.KeySpecParser import helium314.keyboard.keyboard.internal.KeySpecParser
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
import helium314.keyboard.latin.common.Constants import helium314.keyboard.latin.common.Constants
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
@ -19,9 +20,9 @@ class KeySpecParserTest {
@Test fun code() { @Test fun code() {
assertEquals('a'.code, KeySpecParser.getCode("a")) assertEquals('a'.code, KeySpecParser.getCode("a"))
assertEquals('b'.code, KeySpecParser.getCode("a|b")) assertEquals('b'.code, KeySpecParser.getCode("a|b"))
assertEquals(Constants.CODE_OUTPUT_TEXT, KeySpecParser.getCode("hey|there")) assertEquals(KeyCode.MULTIPLE_CODE_POINTS, KeySpecParser.getCode("hey|there"))
assertEquals('c'.code, KeySpecParser.getCode("a|b|c")) assertEquals('c'.code, KeySpecParser.getCode("a|b|c"))
assertEquals(Constants.CODE_OUTPUT_TEXT, KeySpecParser.getCode("a\\|b")) assertEquals(KeyCode.MULTIPLE_CODE_POINTS, KeySpecParser.getCode("a\\|b"))
assertEquals('c'.code, KeySpecParser.getCode("a\\|b|c")) assertEquals('c'.code, KeySpecParser.getCode("a\\|b|c"))
assertEquals('d'.code, KeySpecParser.getCode("a\\|b|c|d")) assertEquals('d'.code, KeySpecParser.getCode("a\\|b|c|d"))
} }

View file

@ -14,6 +14,7 @@ import helium314.keyboard.ShadowLocaleManagerCompat
import helium314.keyboard.event.Event import helium314.keyboard.event.Event
import helium314.keyboard.keyboard.KeyboardSwitcher import helium314.keyboard.keyboard.KeyboardSwitcher
import helium314.keyboard.keyboard.MainKeyboardView import helium314.keyboard.keyboard.MainKeyboardView
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
import helium314.keyboard.latin.ShadowFacilitator2.Companion.lastAddedWord import helium314.keyboard.latin.ShadowFacilitator2.Companion.lastAddedWord
import helium314.keyboard.latin.SuggestedWords.SuggestedWordInfo import helium314.keyboard.latin.SuggestedWords.SuggestedWordInfo
import helium314.keyboard.latin.common.Constants import helium314.keyboard.latin.common.Constants
@ -81,7 +82,7 @@ class InputLogicTest {
@Test fun delete() { @Test fun delete() {
reset() reset()
setText("hello there ") setText("hello there ")
functionalKeyPress(Constants.CODE_DELETE) functionalKeyPress(KeyCode.DELETE)
assertEquals("hello there", text) assertEquals("hello there", text)
assertEquals("there", composingText) assertEquals("there", composingText)
} }
@ -90,7 +91,7 @@ class InputLogicTest {
reset() reset()
setText("hello you there") setText("hello you there")
setCursorPosition(8) // after o in you setCursorPosition(8) // after o in you
functionalKeyPress(Constants.CODE_DELETE) functionalKeyPress(KeyCode.DELETE)
assertEquals("hello yu there", text) assertEquals("hello yu there", text)
// todo: do we really want an empty composing text in this case? // todo: do we really want an empty composing text in this case?
// setting whole word composing will delete text behind cursor // setting whole word composing will delete text behind cursor
@ -245,7 +246,7 @@ class InputLogicTest {
DeviceProtectedUtils.getSharedPreferences(latinIME).edit { putBoolean(Settings.PREF_AUTOSPACE_AFTER_PUNCTUATION, true) } DeviceProtectedUtils.getSharedPreferences(latinIME).edit { putBoolean(Settings.PREF_AUTOSPACE_AFTER_PUNCTUATION, true) }
input("bla") input("bla")
input('.') input('.')
functionalKeyPress(Constants.CODE_SHIFT) // should remove the phantom space (in addition to normal effect) functionalKeyPress(KeyCode.SHIFT) // should remove the phantom space (in addition to normal effect)
input('c') input('c')
assertEquals("bla.c", text) assertEquals("bla.c", text)
assertEquals("bla.c", composingText) assertEquals("bla.c", composingText)
@ -326,9 +327,9 @@ class InputLogicTest {
setInputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI) setInputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI)
setText("http://example.com/here") setText("http://example.com/here")
setCursorPosition(18) // after .com setCursorPosition(18) // after .com
functionalKeyPress(Constants.CODE_DELETE) functionalKeyPress(KeyCode.DELETE)
functionalKeyPress(Constants.CODE_DELETE) functionalKeyPress(KeyCode.DELETE)
functionalKeyPress(Constants.CODE_DELETE) // delete com functionalKeyPress(KeyCode.DELETE) // delete com
// todo: do we really want no composing text? // todo: do we really want no composing text?
// probably not... try not to break composing // probably not... try not to break composing
assertEquals("", composingText) assertEquals("", composingText)
@ -341,8 +342,8 @@ class InputLogicTest {
DeviceProtectedUtils.getSharedPreferences(latinIME).edit { putBoolean(Settings.PREF_URL_DETECTION, true) } DeviceProtectedUtils.getSharedPreferences(latinIME).edit { putBoolean(Settings.PREF_URL_DETECTION, true) }
setText("http://example.com/here") setText("http://example.com/here")
setCursorPosition(18) // after .com setCursorPosition(18) // after .com
functionalKeyPress(Constants.CODE_DELETE) functionalKeyPress(KeyCode.DELETE)
functionalKeyPress(Constants.CODE_DELETE) // delete om functionalKeyPress(KeyCode.DELETE) // delete om
// todo: this is a weird difference to deleting the full TLD (see urlProperlySelected) // todo: this is a weird difference to deleting the full TLD (see urlProperlySelected)
// what do we want here? (probably consistency) // what do we want here? (probably consistency)
assertEquals("example.c/here", composingText) assertEquals("example.c/here", composingText)