diff --git a/java/src/org/futo/inputmethod/accessibility/KeyboardAccessibilityDelegate.java b/java/src/org/futo/inputmethod/accessibility/KeyboardAccessibilityDelegate.java index 03894300e..08d05475d 100644 --- a/java/src/org/futo/inputmethod/accessibility/KeyboardAccessibilityDelegate.java +++ b/java/src/org/futo/inputmethod/accessibility/KeyboardAccessibilityDelegate.java @@ -173,7 +173,7 @@ public class KeyboardAccessibilityDelegate String description = getKeyDescription(k); if(description == null || description.isBlank()) { - Log.e(TAG, "Invalid key has blank description: " + k.toLongString()); + Log.e(TAG, "Invalid key has blank description: " + k.toString()); description = "Unknown"; } diff --git a/java/src/org/futo/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java b/java/src/org/futo/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java index 58996cbe9..bf6d1f340 100644 --- a/java/src/org/futo/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java +++ b/java/src/org/futo/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java @@ -250,10 +250,10 @@ public final class MainKeyboardAccessibilityDelegate // This long press has handled at {@link MainKeyboardView#onLongPress(PointerTracker)}. // We should ignore further hover events on this key. mBoundsToIgnoreHoverEvent.set(key.getHitBox()); - if (key.hasNoPanelAutoMoreKey()) { + if (key.getHasNoPanelAutoMoreKey()) { // This long press has registered a code point without showing a more keys keyboard. // We should talk back the code point if possible. - final int codePointOfNoPanelAutoMoreKey = key.getMoreKeys()[0].mCode; + final int codePointOfNoPanelAutoMoreKey = key.getMoreKeys().get(0).mCode; final String text = KeyCodeDescriptionMapper.getInstance().getDescriptionForCodePoint( mKeyboardView.getContext(), codePointOfNoPanelAutoMoreKey); if (text != null) { diff --git a/java/src/org/futo/inputmethod/keyboard/Key.kt b/java/src/org/futo/inputmethod/keyboard/Key.kt index 5f610ee0c..ed8c5dd43 100644 --- a/java/src/org/futo/inputmethod/keyboard/Key.kt +++ b/java/src/org/futo/inputmethod/keyboard/Key.kt @@ -13,990 +13,433 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package org.futo.inputmethod.keyboard -package org.futo.inputmethod.keyboard; +import android.graphics.Rect +import android.graphics.Typeface +import android.graphics.drawable.Drawable +import android.text.TextUtils +import org.futo.inputmethod.keyboard.internal.KeyDrawParams +import org.futo.inputmethod.keyboard.internal.KeySpecParser +import org.futo.inputmethod.keyboard.internal.KeyStyle +import org.futo.inputmethod.keyboard.internal.KeyVisualAttributes +import org.futo.inputmethod.keyboard.internal.KeyboardIconsSet +import org.futo.inputmethod.keyboard.internal.KeyboardParams +import org.futo.inputmethod.keyboard.internal.MoreKeySpec +import org.futo.inputmethod.keyboard.internal.MoreKeySpec.LettersOnBaseLayout +import org.futo.inputmethod.latin.common.Constants +import org.futo.inputmethod.latin.common.StringUtils +import org.futo.inputmethod.latin.uix.DynamicThemeProvider +import org.futo.inputmethod.v2keyboard.KeyVisualStyle -import static org.futo.inputmethod.keyboard.internal.KeyboardIconsSet.ICON_UNDEFINED; -import static org.futo.inputmethod.latin.common.Constants.CODE_OUTPUT_TEXT; -import static org.futo.inputmethod.latin.common.Constants.CODE_SHIFT; -import static org.futo.inputmethod.latin.common.Constants.CODE_SWITCH_ALPHA_SYMBOL; -import static org.futo.inputmethod.latin.common.Constants.CODE_UNSPECIFIED; -import android.content.res.TypedArray; -import android.graphics.Rect; -import android.graphics.Typeface; -import android.graphics.drawable.Drawable; -import android.text.TextUtils; +data object KeyConsts { + const val LABEL_FLAGS_ALIGN_HINT_LABEL_TO_BOTTOM: Int = 0x02 + const val LABEL_FLAGS_ALIGN_ICON_TO_BOTTOM: Int = 0x04 + const val LABEL_FLAGS_ALIGN_LABEL_OFF_CENTER: Int = 0x08 -import org.futo.inputmethod.keyboard.internal.KeyDrawParams; -import org.futo.inputmethod.keyboard.internal.KeySpecParser; -import org.futo.inputmethod.keyboard.internal.KeyStyle; -import org.futo.inputmethod.keyboard.internal.KeyVisualAttributes; -import org.futo.inputmethod.keyboard.internal.KeyboardIconsSet; -import org.futo.inputmethod.keyboard.internal.KeyboardParams; -import org.futo.inputmethod.keyboard.internal.KeyboardRow; -import org.futo.inputmethod.keyboard.internal.MoreKeySpec; -import org.futo.inputmethod.latin.R; -import org.futo.inputmethod.latin.common.Constants; -import org.futo.inputmethod.latin.common.StringUtils; + // Font typeface specification. + const val LABEL_FLAGS_FONT_MASK: Int = 0x30 + const val LABEL_FLAGS_FONT_NORMAL: Int = 0x10 + const val LABEL_FLAGS_FONT_MONO_SPACE: Int = 0x20 + const val LABEL_FLAGS_FONT_DEFAULT: Int = 0x30 -import java.util.Arrays; -import java.util.Locale; -import java.util.Objects; + // Start of key text ratio enum values + const val LABEL_FLAGS_FOLLOW_KEY_TEXT_RATIO_MASK: Int = 0x1C0 + const val LABEL_FLAGS_FOLLOW_KEY_LARGE_LETTER_RATIO: Int = 0x40 + const val LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO: Int = 0x80 + const val LABEL_FLAGS_FOLLOW_KEY_LABEL_RATIO: Int = 0xC0 + const val LABEL_FLAGS_FOLLOW_KEY_HINT_LABEL_RATIO: Int = 0x140 + + // End of key text ratio mask enum values + const val LABEL_FLAGS_HAS_POPUP_HINT: Int = 0x200 + const val LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT: Int = 0x400 + const val LABEL_FLAGS_HAS_HINT_LABEL: Int = 0x800 + + // The bit to calculate the ratio of key label width against key width. If autoXScale bit is on + // and autoYScale bit is off, the key label may be shrunk only for X-direction. + // If both autoXScale and autoYScale bits are on, the key label text size may be auto scaled. + const val LABEL_FLAGS_AUTO_X_SCALE: Int = 0x4000 + const val LABEL_FLAGS_AUTO_Y_SCALE: Int = 0x8000 + const val LABEL_FLAGS_AUTO_SCALE: Int = (LABEL_FLAGS_AUTO_X_SCALE + or LABEL_FLAGS_AUTO_Y_SCALE) + const val LABEL_FLAGS_PRESERVE_CASE: Int = 0x10000 + const val LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED: Int = 0x20000 + const val LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL: Int = 0x40000 + const val LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR: Int = 0x80000 + const val LABEL_FLAGS_KEEP_BACKGROUND_ASPECT_RATIO: Int = 0x100000 + const val LABEL_FLAGS_DISABLE_HINT_LABEL: Int = 0x40000000 + const val LABEL_FLAGS_DISABLE_ADDITIONAL_MORE_KEYS: Int = -0x80000000 + + const val MORE_KEYS_COLUMN_NUMBER_MASK: Int = 0x000000ff + + // If this flag is specified, more keys keyboard should have the specified number of columns. + // Otherwise more keys keyboard should have less than or equal to the specified maximum number + // of columns. + const val MORE_KEYS_FLAGS_FIXED_COLUMN: Int = 0x00000100 + + // If this flag is specified, the order of more keys is determined by the order in the more + // keys' specification. Otherwise the order of more keys is automatically determined. + const val MORE_KEYS_FLAGS_FIXED_ORDER: Int = 0x00000200 + const val MORE_KEYS_MODE_MAX_COLUMN_WITH_AUTO_ORDER: Int = 0 + const val MORE_KEYS_MODE_FIXED_COLUMN_WITH_AUTO_ORDER: Int = MORE_KEYS_FLAGS_FIXED_COLUMN + const val MORE_KEYS_MODE_FIXED_COLUMN_WITH_FIXED_ORDER: Int = + (MORE_KEYS_FLAGS_FIXED_COLUMN or MORE_KEYS_FLAGS_FIXED_ORDER) + const val MORE_KEYS_FLAGS_HAS_LABELS: Int = 0x40000000 + const val MORE_KEYS_FLAGS_NEEDS_DIVIDERS: Int = 0x20000000 + const val MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY: Int = 0x10000000 + + const val MORE_KEYS_AUTO_COLUMN_ORDER: String = "!autoColumnOrder!" + const val MORE_KEYS_FIXED_COLUMN_ORDER: String = "!fixedColumnOrder!" + const val MORE_KEYS_HAS_LABELS: String = "!hasLabels!" + const val MORE_KEYS_NEEDS_DIVIDERS: String = "!needsDividers!" + const val MORE_KEYS_NO_PANEL_AUTO_MORE_KEY: String = "!noPanelAutoMoreKey!" + + const val BACKGROUND_TYPE_EMPTY: Int = 0 + const val BACKGROUND_TYPE_NORMAL: Int = 1 + const val BACKGROUND_TYPE_FUNCTIONAL: Int = 2 + const val BACKGROUND_TYPE_STICKY_OFF: Int = 3 + const val BACKGROUND_TYPE_STICKY_ON: Int = 4 + const val BACKGROUND_TYPE_ACTION: Int = 5 + const val BACKGROUND_TYPE_SPACEBAR: Int = 6 + + const val ACTION_FLAGS_IS_REPEATABLE: Int = 0x01 + const val ACTION_FLAGS_NO_KEY_PREVIEW: Int = 0x02 + const val ACTION_FLAGS_ALT_CODE_WHILE_TYPING: Int = 0x04 + const val ACTION_FLAGS_ENABLE_LONG_PRESS: Int = 0x08 +} -import javax.annotation.Nonnull; -import javax.annotation.Nullable; /** * Class for describing the position and characteristics of a single key in the keyboard. */ -public class Key implements Comparable { +data class Key( /** * The key code (unicode or custom code) that this key generates. */ - private final int mCode; + val code: Int, - /** Label to display */ - private final String mLabel; - /** Hint label to display on the key in conjunction with the label */ - private final String mHintLabel; - private final String mHintIconId; - /** Flags of the label */ - private final int mLabelFlags; - public static final int LABEL_FLAGS_ALIGN_HINT_LABEL_TO_BOTTOM = 0x02; - public static final int LABEL_FLAGS_ALIGN_ICON_TO_BOTTOM = 0x04; - public static final int LABEL_FLAGS_ALIGN_LABEL_OFF_CENTER = 0x08; - // Font typeface specification. - public static final int LABEL_FLAGS_FONT_MASK = 0x30; - public static final int LABEL_FLAGS_FONT_NORMAL = 0x10; - public static final int LABEL_FLAGS_FONT_MONO_SPACE = 0x20; - public static final int LABEL_FLAGS_FONT_DEFAULT = 0x30; - // Start of key text ratio enum values - public static final int LABEL_FLAGS_FOLLOW_KEY_TEXT_RATIO_MASK = 0x1C0; - public static final int LABEL_FLAGS_FOLLOW_KEY_LARGE_LETTER_RATIO = 0x40; - public static final int LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO = 0x80; - public static final int LABEL_FLAGS_FOLLOW_KEY_LABEL_RATIO = 0xC0; - public static final int LABEL_FLAGS_FOLLOW_KEY_HINT_LABEL_RATIO = 0x140; - // End of key text ratio mask enum values - public static final int LABEL_FLAGS_HAS_POPUP_HINT = 0x200; - public static final int LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT = 0x400; - public static final int LABEL_FLAGS_HAS_HINT_LABEL = 0x800; - // The bit to calculate the ratio of key label width against key width. If autoXScale bit is on - // and autoYScale bit is off, the key label may be shrunk only for X-direction. - // If both autoXScale and autoYScale bits are on, the key label text size may be auto scaled. - public static final int LABEL_FLAGS_AUTO_X_SCALE = 0x4000; - public static final int LABEL_FLAGS_AUTO_Y_SCALE = 0x8000; - public static final int LABEL_FLAGS_AUTO_SCALE = LABEL_FLAGS_AUTO_X_SCALE - | LABEL_FLAGS_AUTO_Y_SCALE; - public static final int LABEL_FLAGS_PRESERVE_CASE = 0x10000; - public static final int LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED = 0x20000; - public static final int LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL = 0x40000; - public static final int LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR = 0x80000; - public static final int LABEL_FLAGS_KEEP_BACKGROUND_ASPECT_RATIO = 0x100000; - public static final int LABEL_FLAGS_DISABLE_HINT_LABEL = 0x40000000; - public static final int LABEL_FLAGS_DISABLE_ADDITIONAL_MORE_KEYS = 0x80000000; + /** Label to display */ + val label: String, - /** Icon to display instead of a label. Icon takes precedence over a label */ - private final String mIconId; + /** Icon to display instead of a label. Icon takes precedence over a label */ + val iconId: String = KeyboardIconsSet.ICON_UNDEFINED, + + /** Hint label to display on the key in conjunction with the label */ + val hintLabel: String? = null, + + /** Hint icon to display instead of hint label. Icon takes precedence over a label */ + val hintIconId: String? = null, + + /** Flags of the label */ + val labelFlags: Int, + + /** Width of the key, minus the gap */ + val width: Int, + + /** Height of the key, minus the gap */ + val height: Int, - /** Width of the key, excluding the gap */ - private final int mWidth; - /** Height of the key, excluding the gap */ - private final int mHeight; /** * The combined width in pixels of the horizontal gaps belonging to this key, both to the left - * and to the right. I.e., mWidth + mHorizontalGap = total width belonging to the key. + * and to the right. I.e., [width] + [horizontalGap] = total width belonging to the key. */ - private final int mHorizontalGap; + val horizontalGap: Int, + /** * The combined height in pixels of the vertical gaps belonging to this key, both above and - * below. I.e., mHeight + mVerticalGap = total height belonging to the key. + * below. I.e., [height] + [verticalGap] = total height belonging to the key. */ - private final int mVerticalGap; - /** X coordinate of the top-left corner of the key in the keyboard layout, excluding the gap. */ - private final int mX; - /** Y coordinate of the top-left corner of the key in the keyboard layout, excluding the gap. */ - private final int mY; - /** Hit bounding box of the key */ - @Nonnull - private final Rect mHitBox = new Rect(); + val verticalGap: Int, - /** More keys. It is guaranteed that this is null or an array of one or more elements */ - @Nullable - private final MoreKeySpec[] mMoreKeys; - /** More keys column number and flags */ - private final int mMoreKeysColumnAndFlags; - public static final int MORE_KEYS_COLUMN_NUMBER_MASK = 0x000000ff; - // If this flag is specified, more keys keyboard should have the specified number of columns. - // Otherwise more keys keyboard should have less than or equal to the specified maximum number - // of columns. - public static final int MORE_KEYS_FLAGS_FIXED_COLUMN = 0x00000100; - // If this flag is specified, the order of more keys is determined by the order in the more - // keys' specification. Otherwise the order of more keys is automatically determined. - public static final int MORE_KEYS_FLAGS_FIXED_ORDER = 0x00000200; - public static final int MORE_KEYS_MODE_MAX_COLUMN_WITH_AUTO_ORDER = 0; - public static final int MORE_KEYS_MODE_FIXED_COLUMN_WITH_AUTO_ORDER = - MORE_KEYS_FLAGS_FIXED_COLUMN; - public static final int MORE_KEYS_MODE_FIXED_COLUMN_WITH_FIXED_ORDER = - (MORE_KEYS_FLAGS_FIXED_COLUMN | MORE_KEYS_FLAGS_FIXED_ORDER); - public static final int MORE_KEYS_FLAGS_HAS_LABELS = 0x40000000; - public static final int MORE_KEYS_FLAGS_NEEDS_DIVIDERS = 0x20000000; - public static final int MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY = 0x10000000; - // TODO: Rename these specifiers to !autoOrder! and !fixedOrder! respectively. - public static final String MORE_KEYS_AUTO_COLUMN_ORDER = "!autoColumnOrder!"; - public static final String MORE_KEYS_FIXED_COLUMN_ORDER = "!fixedColumnOrder!"; - public static final String MORE_KEYS_HAS_LABELS = "!hasLabels!"; - public static final String MORE_KEYS_NEEDS_DIVIDERS = "!needsDividers!"; - public static final String MORE_KEYS_NO_PANEL_AUTO_MORE_KEY = "!noPanelAutoMoreKey!"; + /** X coordinate of the top-left corner of the key in the keyboard layout, excluding the gap. */ + val x: Int, - /** Background type that represents different key background visual than normal one. */ - private int mBackgroundType; - public static final int BACKGROUND_TYPE_EMPTY = 0; - public static final int BACKGROUND_TYPE_NORMAL = 1; - public static final int BACKGROUND_TYPE_FUNCTIONAL = 2; - public static final int BACKGROUND_TYPE_STICKY_OFF = 3; - public static final int BACKGROUND_TYPE_STICKY_ON = 4; - public static final int BACKGROUND_TYPE_ACTION = 5; - public static final int BACKGROUND_TYPE_SPACEBAR = 6; + /** Y coordinate of the top-left corner of the key in the keyboard layout, excluding the gap. */ + val y: Int, - private final int mActionFlags; - public static final int ACTION_FLAGS_IS_REPEATABLE = 0x01; - public static final int ACTION_FLAGS_NO_KEY_PREVIEW = 0x02; - public static final int ACTION_FLAGS_ALT_CODE_WHILE_TYPING = 0x04; - public static final int ACTION_FLAGS_ENABLE_LONG_PRESS = 0x08; + /** Hit bounding box of the key */ + val hitBox: Rect = Rect( + x, y, + x + width + horizontalGap, + y + height + verticalGap + ), - @Nullable - private final KeyVisualAttributes mKeyVisualAttributes; - @Nullable - private final OptionalAttributes mOptionalAttributes; + /** More keys. If the key has no morekeys, this will be an empty list. */ + val moreKeys: List = listOf(), - private static final class OptionalAttributes { - /** Text to output when pressed. This can be multiple characters, like ".com" */ - public final String mOutputText; - public final int mAltCode; - /** The visual insets */ - public final int mVisualInsetsLeft; - public final int mVisualInsetsRight; + /** More keys column number and flags */ + val moreKeysColumnAndFlags: Int = 0, - private OptionalAttributes(final String outputText, final int altCode, final int visualInsetsLeft, final int visualInsetsRight) { - mOutputText = outputText; - mAltCode = altCode; - mVisualInsetsLeft = 0;//visualInsetsLeft; - mVisualInsetsRight = 0;//visualInsetsRight; + /** Background type that represents different key background visual than normal one. */ + val visualStyle: KeyVisualStyle, + + val actionFlags: Int, + + val visualAttributes: KeyVisualAttributes? = null, + + /** Text to output. If set, code should be set to Constants.CODE_OUTPUT_TEXT */ + val outputText: String? = null, + + // Not sure what this is + val altCode: Int = Constants.CODE_UNSPECIFIED, + + /** Backgroundless spacer. Use Constants.CODE_UNSPECIFIED */ + val isSpacer: Boolean = false, + + /** Key is enabled and responds on press */ + val isEnabled: Boolean = code != Constants.CODE_UNSPECIFIED, +) { + /** The current pressed state of this key */ + private var mPressed = false + + /** x position for drawing */ + val drawX: Int = x + horizontalGap / 2 // + visualInsetsLeft + + /** width for drawing */ + val drawWidth: Int = width // - visualInsetsLeft - visualInsetsRight + + /** width + gap */ + val totalWidth = width + horizontalGap + + /** hint label to use, either constructor-specified or from moreKeys */ + val effectiveHintLabel = hintLabel ?: moreKeys.firstOrNull()?.let { + val label = it.mLabel?.let { + if(it.startsWith("\\")) it.substring(1) else it } - @Nullable - public static OptionalAttributes newInstance(final String outputText, final int altCode, final int visualInsetsLeft, final int visualInsetsRight) { - if (outputText == null && altCode == CODE_UNSPECIFIED && visualInsetsLeft == 0 - && visualInsetsRight == 0) { - return null; - } - return new OptionalAttributes(outputText, altCode, visualInsetsLeft, - visualInsetsRight); - } - } - - private final int mHashCode; - - /** The current pressed state of this key */ - private boolean mPressed; - /** Key is enabled and responds on press */ - private boolean mEnabled = true; - - /** - * Constructor for a key on MoreKeyKeyboard, on MoreSuggestions, - * and in a . - */ - public Key(@Nullable final String label, final String iconId, final int code, - @Nullable final String outputText, @Nullable final String hintLabel, - final int labelFlags, final int backgroundType, final int x, final int y, - final int width, final int height, final int horizontalGap, final int verticalGap, - final int actionFlags) { - mWidth = width - horizontalGap; - mHeight = height - verticalGap; - mHorizontalGap = horizontalGap; - mVerticalGap = verticalGap; - mHintLabel = hintLabel; - mHintIconId = ICON_UNDEFINED; - mLabelFlags = labelFlags; - mBackgroundType = backgroundType; - mActionFlags = actionFlags; - mMoreKeys = null; - mMoreKeysColumnAndFlags = 0; - mLabel = label; - mOptionalAttributes = OptionalAttributes.newInstance(outputText, CODE_UNSPECIFIED, 0 /* visualInsetsLeft */, 0 /* visualInsetsRight */); - mCode = code; - mEnabled = (code != CODE_UNSPECIFIED); - mIconId = iconId; - // Horizontal gap is divided equally to both sides of the key. - mX = x + mHorizontalGap / 2; - mY = y; - mHitBox.set(x, y, x + width + 1, y + height); - mKeyVisualAttributes = null; - - mHashCode = computeHashCode(this); - } - - /** - * Create a key with the given top-left coordinate and extract its attributes from a key - * specification string, Key attribute array, key style, and etc. - * - * @param keySpec the key specification. - * @param keyAttr the Key XML attributes array. - * @param style the {@link KeyStyle} of this key. - * @param params the keyboard building parameters. - * @param row the row that this key belongs to. row's x-coordinate will be the right edge of - * this key. - */ - public Key(@Nullable final String keySpec, @Nonnull final TypedArray keyAttr, - @Nonnull final KeyStyle style, @Nonnull final KeyboardParams params, - @Nonnull final KeyboardRow row) { - mHorizontalGap = isSpacer() ? 0 : params.mHorizontalGap; - mVerticalGap = params.mVerticalGap; - - final float horizontalGapFloat = mHorizontalGap; - final int rowHeight = row.getRowHeight(); - mHeight = rowHeight - mVerticalGap; - - final float keyXPos = row.getKeyX(keyAttr); - final float keyWidth = row.getKeyWidth(keyAttr, keyXPos); - final int keyYPos = row.getKeyY(); - - // Horizontal gap is divided equally to both sides of the key. - mX = Math.round(keyXPos + horizontalGapFloat / 2); - mY = keyYPos; - mWidth = Math.round(keyWidth - horizontalGapFloat); - mHitBox.set(Math.round(keyXPos), keyYPos, Math.round(keyXPos + keyWidth) + 1, - keyYPos + rowHeight); - // Update row to have current x coordinate. - row.setXPos(keyXPos + keyWidth); - - mBackgroundType = style.getInt(keyAttr, - R.styleable.Keyboard_Key_backgroundType, row.getDefaultBackgroundType()); - - final int baseWidth = params.mBaseWidth; - final int visualInsetsLeft = Math.round(keyAttr.getFraction( - R.styleable.Keyboard_Key_visualInsetsLeft, baseWidth, baseWidth, 0)); - final int visualInsetsRight = Math.round(keyAttr.getFraction( - R.styleable.Keyboard_Key_visualInsetsRight, baseWidth, baseWidth, 0)); - - if((visualInsetsLeft > 0 || visualInsetsRight > 0) && mBackgroundType != BACKGROUND_TYPE_STICKY_ON) { - mBackgroundType = BACKGROUND_TYPE_FUNCTIONAL; - } - - mLabelFlags = style.getFlags(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags) - | row.getDefaultKeyLabelFlags(); - final boolean needsToUpcase = needsToUpcase(mLabelFlags, params.mId.mElementId); - final Locale localeForUpcasing = params.mId.getLocale(); - int actionFlags = style.getFlags(keyAttr, R.styleable.Keyboard_Key_keyActionFlags); - - String[] moreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys, s -> params.mId.mLongPressKeySettings.reorderMoreKeys(s)); - - // Get maximum column order number and set a relevant mode value. - int moreKeysColumnAndFlags = MORE_KEYS_MODE_MAX_COLUMN_WITH_AUTO_ORDER - | style.getInt(keyAttr, R.styleable.Keyboard_Key_maxMoreKeysColumn, - params.mMaxMoreKeysKeyboardColumn); - int value; - if ((value = MoreKeySpec.getIntValue(moreKeys, MORE_KEYS_AUTO_COLUMN_ORDER, -1)) > 0) { - // Override with fixed column order number and set a relevant mode value. - moreKeysColumnAndFlags = MORE_KEYS_MODE_FIXED_COLUMN_WITH_AUTO_ORDER - | (value & MORE_KEYS_COLUMN_NUMBER_MASK); - } - if ((value = MoreKeySpec.getIntValue(moreKeys, MORE_KEYS_FIXED_COLUMN_ORDER, -1)) > 0) { - // Override with fixed column order number and set a relevant mode value. - moreKeysColumnAndFlags = MORE_KEYS_MODE_FIXED_COLUMN_WITH_FIXED_ORDER - | (value & MORE_KEYS_COLUMN_NUMBER_MASK); - } - if (MoreKeySpec.getBooleanValue(moreKeys, MORE_KEYS_HAS_LABELS)) { - moreKeysColumnAndFlags |= MORE_KEYS_FLAGS_HAS_LABELS; - } - if (MoreKeySpec.getBooleanValue(moreKeys, MORE_KEYS_NEEDS_DIVIDERS)) { - moreKeysColumnAndFlags |= MORE_KEYS_FLAGS_NEEDS_DIVIDERS; - } - if (MoreKeySpec.getBooleanValue(moreKeys, MORE_KEYS_NO_PANEL_AUTO_MORE_KEY)) { - moreKeysColumnAndFlags |= MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY; - } - mMoreKeysColumnAndFlags = moreKeysColumnAndFlags; - - final String[] additionalMoreKeys; - if ((mLabelFlags & LABEL_FLAGS_DISABLE_ADDITIONAL_MORE_KEYS) != 0) { - additionalMoreKeys = null; + if(it.mNeedsToUpperCase) { + StringUtils.toTitleCaseOfKeyLabel(label, it.mLocale) } else { - additionalMoreKeys = style.getStringArray(keyAttr, - R.styleable.Keyboard_Key_additionalMoreKeys, null); - } - moreKeys = MoreKeySpec.insertAdditionalMoreKeys(moreKeys, additionalMoreKeys); - - boolean shouldSuppressNumbersInMoreKeys = moreKeys != null && - // Number row is active - params.mId.mNumberRow && - // This key is not part of number row - style.getFlags(keyAttr, R.styleable.Keyboard_Key_doNotSuppressNumbersInMoreKeys) == 0; - - if(shouldSuppressNumbersInMoreKeys) { - moreKeys = Arrays.stream(moreKeys) - .filter(s -> !s.matches("\\d+")) - .toArray(String[]::new); - } - - if (moreKeys != null && moreKeys.length > 0) { - actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS; - mMoreKeys = new MoreKeySpec[moreKeys.length]; - for (int i = 0; i < moreKeys.length; i++) { - mMoreKeys[i] = new MoreKeySpec(moreKeys[i], needsToUpcase, localeForUpcasing); - } - } else { - mMoreKeys = null; - } - mActionFlags = actionFlags; - - mIconId = KeySpecParser.getIconId(keySpec); - - final int code = KeySpecParser.getCode(keySpec); - if ((mLabelFlags & LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL) != 0) { - mLabel = params.mId.mCustomActionLabel; - } else if (code >= Character.MIN_SUPPLEMENTARY_CODE_POINT) { - // This is a workaround to have a key that has a supplementary code point in its label. - // Because we can put a string in resource neither as a XML entity of a supplementary - // code point nor as a surrogate pair. - mLabel = new StringBuilder().appendCodePoint(code).toString(); - } else { - final String label = KeySpecParser.getLabel(keySpec); - mLabel = needsToUpcase - ? StringUtils.toTitleCaseOfKeyLabel(label, localeForUpcasing) - : label; - } - - if ((mLabelFlags & LABEL_FLAGS_DISABLE_HINT_LABEL) != 0) { - mHintLabel = null; - mHintIconId = null; - } else { - String hintLabel = null; - String hintIcon = null; - - if(moreKeys != null && moreKeys.length > 0) { - String hintLabelCandidate = moreKeys[0]; - if(hintLabelCandidate.startsWith("\\")) hintLabelCandidate = hintLabelCandidate.substring(1); - - if(hintLabelCandidate.length() < 3) { - hintLabel = needsToUpcase - ? StringUtils.toTitleCaseOfKeyLabel(hintLabelCandidate, localeForUpcasing) - : hintLabelCandidate; - } else if(hintLabelCandidate.contains("!icon/")) { - hintIcon = KeySpecParser.getIconId(hintLabelCandidate); - } - } - - mHintLabel = hintLabel; - mHintIconId = hintIcon; - } - - String outputText = KeySpecParser.getOutputText(keySpec); - if (needsToUpcase) { - outputText = StringUtils.toTitleCaseOfKeyLabel(outputText, localeForUpcasing); - } - // Choose the first letter of the label as primary code if not specified. - if (code == CODE_UNSPECIFIED && TextUtils.isEmpty(outputText) - && !TextUtils.isEmpty(mLabel)) { - if (StringUtils.codePointCount(mLabel) == 1) { - // Use the first letter of the hint label if shiftedLetterActivated flag is - // specified. - if (hasShiftedLetterHint() && isShiftedLetterActivated()) { - mCode = mHintLabel.codePointAt(0); - } else { - mCode = mLabel.codePointAt(0); - } - } else { - // In some locale and case, the character might be represented by multiple code - // points, such as upper case Eszett of German alphabet. - outputText = mLabel; - mCode = CODE_OUTPUT_TEXT; - } - } else if (code == CODE_UNSPECIFIED && outputText != null) { - if (StringUtils.codePointCount(outputText) == 1) { - mCode = outputText.codePointAt(0); - outputText = null; - } else { - mCode = CODE_OUTPUT_TEXT; - } - } else { - mCode = needsToUpcase ? StringUtils.toTitleCaseOfKeyCode(code, localeForUpcasing) - : code; - } - final int altCodeInAttr = KeySpecParser.parseCode( - style.getString(keyAttr, R.styleable.Keyboard_Key_altCode, null), CODE_UNSPECIFIED); - final int altCode = needsToUpcase - ? StringUtils.toTitleCaseOfKeyCode(altCodeInAttr, localeForUpcasing) - : altCodeInAttr; - mOptionalAttributes = OptionalAttributes.newInstance(outputText, altCode, visualInsetsLeft, visualInsetsRight); - mKeyVisualAttributes = KeyVisualAttributes.newInstance(keyAttr, null); - mHashCode = computeHashCode(this); - } - - /** - * Copy constructor for DynamicGridKeyboard.GridKey. - * - * @param key the original key. - */ - protected Key(@Nonnull final Key key) { - this(key, key.mMoreKeysColumnAndFlags, key.mMoreKeys); - } - - public Key(@Nonnull final Key key, final int moreKeysColumnAndFlags, @Nullable final MoreKeySpec[] moreKeys) { - // Final attributes. - mCode = key.mCode; - mLabel = key.mLabel; - mLabelFlags = key.mLabelFlags; - mIconId = key.mIconId; - mWidth = key.mWidth; - mHeight = key.mHeight; - mHorizontalGap = key.mHorizontalGap; - mVerticalGap = key.mVerticalGap; - mX = key.mX; - mY = key.mY; - mHitBox.set(key.mHitBox); - mMoreKeys = moreKeys; - mMoreKeysColumnAndFlags = moreKeysColumnAndFlags; - mBackgroundType = key.mBackgroundType; - mActionFlags = key.mActionFlags; - mKeyVisualAttributes = key.mKeyVisualAttributes; - mOptionalAttributes = key.mOptionalAttributes; - mHashCode = key.mHashCode; - // Key state. - mPressed = key.mPressed; - mEnabled = key.mEnabled; - - - if (((mLabelFlags & LABEL_FLAGS_DISABLE_HINT_LABEL) != 0) || moreKeys == null || moreKeys.length == 0 || moreKeys[0].mLabel == null) { - mHintLabel = key.mHintLabel; - mHintIconId = key.mHintIconId; - } else { - String hintLabel = null; - String hintIcon = null; - - String hintLabelCandidate = moreKeys[0].mLabel; - if(hintLabelCandidate.startsWith("\\")) hintLabelCandidate = hintLabelCandidate.substring(1); - - if(hintLabelCandidate.length() < 3) { - hintLabel = moreKeys[0].mNeedsToUpperCase - ? StringUtils.toTitleCaseOfKeyLabel(hintLabelCandidate, moreKeys[0].mLocale) - : hintLabelCandidate; - } else if(hintLabelCandidate.contains("!icon/")) { - hintIcon = KeySpecParser.getIconId(hintLabelCandidate); - } - - mHintLabel = hintLabel; - mHintIconId = hintIcon; + label } } - @Nonnull - public static Key removeRedundantMoreKeys(@Nonnull final Key key, - @Nonnull final MoreKeySpec.LettersOnBaseLayout lettersOnBaseLayout, boolean onlyDuplicateKeys) { - final MoreKeySpec[] moreKeys = key.getMoreKeys(); - - MoreKeySpec[] clearedMoreKeys; - - clearedMoreKeys = MoreKeySpec.removeDuplicateMoreKeys(key.mCode, moreKeys); - - if(!onlyDuplicateKeys) { - clearedMoreKeys = MoreKeySpec.removeRedundantMoreKeys( - clearedMoreKeys, lettersOnBaseLayout); - } - return (clearedMoreKeys == moreKeys) ? key : new Key(key, key.mMoreKeysColumnAndFlags, clearedMoreKeys); + /** hint icon to use, either constructor-specified or from moreKeys */ + val effectiveHintIcon = hintIconId ?: moreKeys.firstOrNull()?.let { + it.mIconId ?: KeySpecParser.getIconId(it.mLabel) } - private static boolean needsToUpcase(final int labelFlags, final int keyboardElementId) { - if ((labelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0) return false; - switch (keyboardElementId) { - case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED: - case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED: - case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED: - case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED: - return true; - default: - return false; - } + + val isAlignIconToBottom = + (labelFlags and KeyConsts.LABEL_FLAGS_ALIGN_ICON_TO_BOTTOM) != 0 + + val isAlignLabelOffCenter = + (labelFlags and KeyConsts.LABEL_FLAGS_ALIGN_LABEL_OFF_CENTER) != 0 + + val hasPopupHint = + (labelFlags and KeyConsts.LABEL_FLAGS_HAS_POPUP_HINT) != 0 + + val hasShiftedLetterHint = + ((labelFlags and KeyConsts.LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT) != 0 + && !TextUtils.isEmpty(effectiveHintLabel)) + + val hasHintLabel = (labelFlags and KeyConsts.LABEL_FLAGS_HAS_HINT_LABEL) != 0 + + val needsAutoXScale = (labelFlags and KeyConsts.LABEL_FLAGS_AUTO_X_SCALE) != 0 + + val needsAutoScale = + (labelFlags and KeyConsts.LABEL_FLAGS_AUTO_SCALE) == KeyConsts.LABEL_FLAGS_AUTO_SCALE + + val hasCustomActionLabel = + (labelFlags and KeyConsts.LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL) != 0 + + private val isShiftedLetterActivated = + ((labelFlags and KeyConsts.LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) != 0 + && !TextUtils.isEmpty(effectiveHintLabel)) + + val moreKeysColumnNumber = + moreKeysColumnAndFlags and KeyConsts.MORE_KEYS_COLUMN_NUMBER_MASK + + val isMoreKeysFixedColumn = + (moreKeysColumnAndFlags and KeyConsts.MORE_KEYS_FLAGS_FIXED_COLUMN) != 0 + + val isMoreKeysFixedOrder = + (moreKeysColumnAndFlags and KeyConsts.MORE_KEYS_FLAGS_FIXED_ORDER) != 0 + + val hasLabelsInMoreKeys = + (moreKeysColumnAndFlags and KeyConsts.MORE_KEYS_FLAGS_HAS_LABELS) != 0 + + val moreKeyLabelFlags = run { + val labelSizeFlag = if (hasLabelsInMoreKeys) + KeyConsts.LABEL_FLAGS_FOLLOW_KEY_LABEL_RATIO + else + KeyConsts.LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO + + labelSizeFlag or KeyConsts.LABEL_FLAGS_AUTO_X_SCALE } - private static int computeHashCode(final Key key) { - return Arrays.hashCode(new Object[] { - key.mX, - key.mY, - key.mWidth, - key.mHeight, - key.mCode, - key.mLabel, - key.mHintLabel, - key.mHintIconId, - key.mIconId, - key.mBackgroundType, - Arrays.hashCode(key.mMoreKeys), - key.getOutputText(), - key.mActionFlags, - key.mLabelFlags, - // Key can be distinguishable without the following members. - // key.mOptionalAttributes.mAltCode, - // key.mOptionalAttributes.mDisabledIconId, - // key.mOptionalAttributes.mPreviewIconId, - // key.mHorizontalGap, - // key.mVerticalGap, - // key.mOptionalAttributes.mVisualInsetLeft, - // key.mOptionalAttributes.mVisualInsetRight, - // key.mMaxMoreKeysColumn, - }); - } + val needsDividersInMoreKeys = + (moreKeysColumnAndFlags and KeyConsts.MORE_KEYS_FLAGS_NEEDS_DIVIDERS) != 0 - private boolean equalsInternal(final Key o) { - if (this == o) return true; - return o.mX == mX - && o.mY == mY - && o.mWidth == mWidth - && o.mHeight == mHeight - && o.mCode == mCode - && TextUtils.equals(o.mLabel, mLabel) - && TextUtils.equals(o.mHintLabel, mHintLabel) - && TextUtils.equals(o.mHintIconId, mHintIconId) - && Objects.equals(o.mIconId, mIconId) - && o.mBackgroundType == mBackgroundType - && Arrays.equals(o.mMoreKeys, mMoreKeys) - && TextUtils.equals(o.getOutputText(), getOutputText()) - && o.mActionFlags == mActionFlags - && o.mLabelFlags == mLabelFlags; - } + val hasNoPanelAutoMoreKey = + (moreKeysColumnAndFlags and KeyConsts.MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY) != 0 - @Override - public int compareTo(Key o) { - if (equalsInternal(o)) return 0; - if (mHashCode > o.mHashCode) return 1; - return -1; - } - @Override - public int hashCode() { - return mHashCode; - } + val isActionKey: Boolean = visualStyle == KeyVisualStyle.Action - @Override - public boolean equals(final Object o) { - return o instanceof Key && equalsInternal((Key)o); - } + val isShift: Boolean = code == Constants.CODE_SHIFT - @Override - public String toString() { - return toShortString() + " " + getX() + "," + getY() + " " + getWidth() + "x" + getHeight(); - } + val isModifier: Boolean = code == Constants.CODE_SHIFT || code == Constants.CODE_SWITCH_ALPHA_SYMBOL - public String toShortString() { - final int code = getCode(); - if (code == Constants.CODE_OUTPUT_TEXT) { - return getOutputText(); - } - return Constants.printableCode(code); - } + val isRepeatable: Boolean = (actionFlags and KeyConsts.ACTION_FLAGS_IS_REPEATABLE) != 0 - public String toLongString() { - final String iconId = getIconId(); - final String topVisual = (Objects.equals(iconId, ICON_UNDEFINED)) - ? KeyboardIconsSet.PREFIX_ICON + iconId : getLabel(); - final String hintLabel = getHintLabel(); - final String visual = (hintLabel == null) ? topVisual : topVisual + "^" + hintLabel; - return toString() + " " + visual + "/" + backgroundName(mBackgroundType); - } + val noKeyPreview: Boolean = (actionFlags and KeyConsts.ACTION_FLAGS_NO_KEY_PREVIEW) != 0 - private static String backgroundName(final int backgroundType) { - switch (backgroundType) { - case BACKGROUND_TYPE_EMPTY: return "empty"; - case BACKGROUND_TYPE_NORMAL: return "normal"; - case BACKGROUND_TYPE_FUNCTIONAL: return "functional"; - case BACKGROUND_TYPE_STICKY_OFF: return "stickyOff"; - case BACKGROUND_TYPE_STICKY_ON: return "stickyOn"; - case BACKGROUND_TYPE_ACTION: return "action"; - case BACKGROUND_TYPE_SPACEBAR: return "spacebar"; - default: return null; - } - } + val altCodeWhileTyping: Boolean = (actionFlags and KeyConsts.ACTION_FLAGS_ALT_CODE_WHILE_TYPING) != 0 - public int getCode() { - return mCode; - } - - @Nullable - public String getLabel() { - return mLabel; - } - - @Nullable - public String getHintLabel() { - return mHintLabel; - } - - @Nullable - public String getHintIconId() { - return mHintIconId; - } - - @Nullable - public MoreKeySpec[] getMoreKeys() { - return mMoreKeys; - } - - public void markAsLeftEdge(final KeyboardParams params) { - mHitBox.left = params.mLeftPadding; - } - - public void markAsRightEdge(final KeyboardParams params) { - mHitBox.right = params.mOccupiedWidth - params.mRightPadding; - } - - public void markAsTopEdge(final KeyboardParams params) { - mHitBox.top = params.mTopPadding; - } - - public void markAsBottomEdge(final KeyboardParams params) { - mHitBox.bottom = params.mOccupiedHeight + params.mBottomPadding; - } - - public final boolean isSpacer() { - return this instanceof Spacer; - } - - public final boolean isActionKey() { - return mBackgroundType == BACKGROUND_TYPE_ACTION; - } - - public final boolean isShift() { - return mCode == CODE_SHIFT; - } - - public final boolean isModifier() { - return mCode == CODE_SHIFT || mCode == CODE_SWITCH_ALPHA_SYMBOL; - } - - public final boolean isRepeatable() { - return (mActionFlags & ACTION_FLAGS_IS_REPEATABLE) != 0; - } - - public final boolean noKeyPreview() { - return (mActionFlags & ACTION_FLAGS_NO_KEY_PREVIEW) != 0; - } - - public final boolean altCodeWhileTyping() { - return (mActionFlags & ACTION_FLAGS_ALT_CODE_WHILE_TYPING) != 0; - } - - public final boolean isLongPressEnabled() { + val isLongPressEnabled: Boolean = // We need not start long press timer on the key which has activated shifted letter. - return (mActionFlags & ACTION_FLAGS_ENABLE_LONG_PRESS) != 0 - && (mLabelFlags & LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) == 0; + ((actionFlags and KeyConsts.ACTION_FLAGS_ENABLE_LONG_PRESS) != 0 + && (labelFlags and KeyConsts.LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) == 0) + + fun markAsLeftEdge(params: KeyboardParams) { + hitBox.left = params.mLeftPadding } - public KeyVisualAttributes getVisualAttributes() { - return mKeyVisualAttributes; + fun markAsRightEdge(params: KeyboardParams) { + hitBox.right = params.mOccupiedWidth - params.mRightPadding } - @Nonnull - public final Typeface selectTypeface(final KeyDrawParams params) { - switch (mLabelFlags & LABEL_FLAGS_FONT_MASK) { - case LABEL_FLAGS_FONT_NORMAL: - return Typeface.DEFAULT; - case LABEL_FLAGS_FONT_MONO_SPACE: - return Typeface.MONOSPACE; - case LABEL_FLAGS_FONT_DEFAULT: - default: - // The type-face is specified by keyTypeface attribute. - return params.mTypeface; + fun markAsTopEdge(params: KeyboardParams) { + hitBox.top = params.mTopPadding + } + + fun markAsBottomEdge(params: KeyboardParams) { + hitBox.bottom = params.mOccupiedHeight + params.mBottomPadding + } + + fun selectTypeface(params: KeyDrawParams): Typeface { + return when (labelFlags and KeyConsts.LABEL_FLAGS_FONT_MASK) { + KeyConsts.LABEL_FLAGS_FONT_NORMAL -> Typeface.DEFAULT + KeyConsts.LABEL_FLAGS_FONT_MONO_SPACE -> Typeface.MONOSPACE + KeyConsts.LABEL_FLAGS_FONT_DEFAULT -> // The type-face is specified by keyTypeface attribute. + params.mTypeface + + else -> + params.mTypeface } } - public final int selectTextSize(final KeyDrawParams params) { - switch (mLabelFlags & LABEL_FLAGS_FOLLOW_KEY_TEXT_RATIO_MASK) { - case LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO: - return params.mLetterSize; - case LABEL_FLAGS_FOLLOW_KEY_LARGE_LETTER_RATIO: - return params.mLargeLetterSize; - case LABEL_FLAGS_FOLLOW_KEY_LABEL_RATIO: - return params.mLabelSize; - case LABEL_FLAGS_FOLLOW_KEY_HINT_LABEL_RATIO: - return params.mHintLabelSize; - default: // No follow key ratio flag specified. - return StringUtils.codePointCount(mLabel) == 1 ? params.mLetterSize : params.mLabelSize; + fun selectTextSize(params: KeyDrawParams): Int { + return when (labelFlags and KeyConsts.LABEL_FLAGS_FOLLOW_KEY_TEXT_RATIO_MASK) { + KeyConsts.LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO -> params.mLetterSize + KeyConsts.LABEL_FLAGS_FOLLOW_KEY_LARGE_LETTER_RATIO -> params.mLargeLetterSize + KeyConsts.LABEL_FLAGS_FOLLOW_KEY_LABEL_RATIO -> params.mLabelSize + KeyConsts.LABEL_FLAGS_FOLLOW_KEY_HINT_LABEL_RATIO -> params.mHintLabelSize + else -> if (StringUtils.codePointCount(label) == 1) params.mLetterSize else params.mLabelSize } } - public final int selectTextColor(final KeyDrawParams params) { - if (isActionKey()) { - return params.mActionKeyTextColor; + fun selectTextColor(provider: DynamicThemeProvider, params: KeyDrawParams): Int { + return provider.getKeyStyleDescriptor(visualStyle).let { style -> + when { + mPressed -> style.foregroundColorPressed + else -> style.foregroundColor + } } - - if ((mLabelFlags & LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR) != 0) { - return params.mFunctionalTextColor; - } - if (mPressed) { - return params.mPressedTextColor; - } - - return isShiftedLetterActivated() ? params.mTextInactivatedColor : params.mTextColor; } - public final int selectHintTextSize(final KeyDrawParams params) { - if (hasHintLabel()) { - return params.mHintLabelSize; + fun selectBackground(provider: DynamicThemeProvider): Drawable? { + return provider.getKeyStyleDescriptor(visualStyle).let { style -> + when { + mPressed -> style.backgroundDrawablePressed + else -> style.backgroundDrawable + } } - if (hasShiftedLetterHint()) { - return params.mShiftedLetterHintSize; + } + + fun selectHintTextSize(provider: DynamicThemeProvider, params: KeyDrawParams): Int { + if (hasHintLabel) { + return params.mHintLabelSize } - return params.mHintLetterSize; - } - - public final int selectHintTextColor(final KeyDrawParams params) { - if (hasHintLabel()) { - return params.mHintLabelColor; + if (hasShiftedLetterHint) { + return params.mShiftedLetterHintSize } - if (hasShiftedLetterHint()) { - return isShiftedLetterActivated() ? params.mShiftedLetterHintActivatedColor - : params.mShiftedLetterHintInactivatedColor; + return params.mHintLetterSize + } + + fun selectHintTextColor(provider: DynamicThemeProvider, params: KeyDrawParams): Int { + if (hasHintLabel) { + return params.mHintLabelColor } - return params.mHintLetterColor; + if (hasShiftedLetterHint) { + return if (isShiftedLetterActivated) params.mShiftedLetterHintActivatedColor + else params.mShiftedLetterHintInactivatedColor + } + return params.mHintLetterColor } - public final int selectMoreKeyTextSize(final KeyDrawParams params) { - return hasLabelsInMoreKeys() ? params.mLabelSize : params.mLetterSize; + fun selectMoreKeyTextSize(params: KeyDrawParams): Int { + return if (hasLabelsInMoreKeys) params.mLabelSize else params.mLetterSize } - public final String getPreviewLabel() { - return isShiftedLetterActivated() ? mHintLabel : mLabel; + val previewLabel: String? + get() = if (isShiftedLetterActivated) hintLabel else label + + private fun previewHasLetterSize(): Boolean { + return ((labelFlags and KeyConsts.LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO) != 0 + || StringUtils.codePointCount(previewLabel) == 1) } - private boolean previewHasLetterSize() { - return (mLabelFlags & LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO) != 0 - || StringUtils.codePointCount(getPreviewLabel()) == 1; + fun selectPreviewTextSize(params: KeyDrawParams): Int { + return params.mPreviewTextSize } - public final int selectPreviewTextSize(final KeyDrawParams params) { - return params.mPreviewTextSize; - } - - @Nonnull - public Typeface selectPreviewTypeface(final KeyDrawParams params) { + fun selectPreviewTypeface(params: KeyDrawParams): Typeface { if (previewHasLetterSize()) { - return selectTypeface(params); + return selectTypeface(params) } - return Typeface.DEFAULT_BOLD; + return Typeface.DEFAULT_BOLD } - public final boolean isAlignHintLabelToBottom(final int defaultFlags) { - return ((mLabelFlags | defaultFlags) & LABEL_FLAGS_ALIGN_HINT_LABEL_TO_BOTTOM) != 0; + fun isAlignHintLabelToBottom(defaultFlags: Int): Boolean { + return ((labelFlags or defaultFlags) and KeyConsts.LABEL_FLAGS_ALIGN_HINT_LABEL_TO_BOTTOM) != 0 } - public final boolean isAlignIconToBottom() { - return (mLabelFlags & LABEL_FLAGS_ALIGN_ICON_TO_BOTTOM) != 0; + fun needsToKeepBackgroundAspectRatio(defaultFlags: Int): Boolean { + return ((labelFlags or defaultFlags) and KeyConsts.LABEL_FLAGS_KEEP_BACKGROUND_ASPECT_RATIO) != 0 } - public final boolean isAlignLabelOffCenter() { - return (mLabelFlags & LABEL_FLAGS_ALIGN_LABEL_OFF_CENTER) != 0; - } - - public final boolean hasPopupHint() { - return (mLabelFlags & LABEL_FLAGS_HAS_POPUP_HINT) != 0; - } - - public final boolean hasShiftedLetterHint() { - return (mLabelFlags & LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT) != 0 - && !TextUtils.isEmpty(mHintLabel); - } - - public final boolean hasHintLabel() { - return (mLabelFlags & LABEL_FLAGS_HAS_HINT_LABEL) != 0; - } - - public final boolean needsAutoXScale() { - return (mLabelFlags & LABEL_FLAGS_AUTO_X_SCALE) != 0; - } - - public final boolean needsAutoScale() { - return (mLabelFlags & LABEL_FLAGS_AUTO_SCALE) == LABEL_FLAGS_AUTO_SCALE; - } - - public final boolean needsToKeepBackgroundAspectRatio(final int defaultFlags) { - return ((mLabelFlags | defaultFlags) & LABEL_FLAGS_KEEP_BACKGROUND_ASPECT_RATIO) != 0; - } - - public final boolean hasCustomActionLabel() { - return (mLabelFlags & LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL) != 0; - } - - private final boolean isShiftedLetterActivated() { - return (mLabelFlags & LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) != 0 - && !TextUtils.isEmpty(mHintLabel); - } - - public final int getMoreKeysColumnNumber() { - return mMoreKeysColumnAndFlags & MORE_KEYS_COLUMN_NUMBER_MASK; - } - - public final boolean isMoreKeysFixedColumn() { - return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_FIXED_COLUMN) != 0; - } - - public final boolean isMoreKeysFixedOrder() { - return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_FIXED_ORDER) != 0; - } - - public final boolean hasLabelsInMoreKeys() { - return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_HAS_LABELS) != 0; - } - - public final int getMoreKeyLabelFlags() { - final int labelSizeFlag = hasLabelsInMoreKeys() - ? LABEL_FLAGS_FOLLOW_KEY_LABEL_RATIO - : LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO; - return labelSizeFlag | LABEL_FLAGS_AUTO_X_SCALE; - } - - public final boolean needsDividersInMoreKeys() { - return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_NEEDS_DIVIDERS) != 0; - } - - public final boolean hasNoPanelAutoMoreKey() { - return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY) != 0; - } - - @Nullable - public final String getOutputText() { - final OptionalAttributes attrs = mOptionalAttributes; - return (attrs != null) ? attrs.mOutputText : null; - } - - public final int getAltCode() { - final OptionalAttributes attrs = mOptionalAttributes; - return (attrs != null) ? attrs.mAltCode : CODE_UNSPECIFIED; - } - - public String getIconId() { - return mIconId; - } - - @Nullable - public Drawable getIcon(final KeyboardIconsSet iconSet, final int alpha) { - final OptionalAttributes attrs = mOptionalAttributes; - final String iconId = getIconId(); - final Drawable icon = iconSet.getIconDrawable(iconId); + fun getIcon(iconSet: KeyboardIconsSet, alpha: Int): Drawable? { + val iconId = iconId + val icon = iconSet.getIconDrawable(iconId) if (icon != null) { - icon.setAlpha(alpha); + icon.alpha = alpha } - return icon; + return icon } - @Nullable - public Drawable getHintIcon(final KeyboardIconsSet iconSet, final int alpha) { - final OptionalAttributes attrs = mOptionalAttributes; - final String iconId = getHintIconId(); - if(iconId == null) return null; + fun getHintIcon(iconSet: KeyboardIconsSet, alpha: Int): Drawable? { + val iconId = effectiveHintIcon ?: return null - final Drawable icon = iconSet.getIconDrawable(iconId); + val icon = iconSet.getIconDrawable(iconId) if (icon != null) { - icon.setAlpha(alpha); + icon.alpha = alpha } - return icon; + return icon } - @Nullable - public Drawable getPreviewIcon(final KeyboardIconsSet iconSet) { - return iconSet.getIconDrawable(getIconId()); - } - - /** - * Gets the width of the key in pixels, excluding the gap. - * @return The width of the key in pixels, excluding the gap. - */ - public int getWidth() { - return mWidth; - } - - /** - * Gets the height of the key in pixels, excluding the gap. - * @return The height of the key in pixels, excluding the gap. - */ - public int getHeight() { - return mHeight; - } - - /** - * The combined width in pixels of the horizontal gaps belonging to this key, both above and - * below. I.e., getWidth() + getHorizontalGap() = total width belonging to the key. - * @return Horizontal gap belonging to this key. - */ - public int getHorizontalGap() { - return mHorizontalGap; - } - - /** - * The combined height in pixels of the vertical gaps belonging to this key, both above and - * below. I.e., getHeight() + getVerticalGap() = total height belonging to the key. - * @return Vertical gap belonging to this key. - */ - public int getVerticalGap() { - return mVerticalGap; - } - - /** - * Gets the x-coordinate of the top-left corner of the key in pixels, excluding the gap. - * @return The x-coordinate of the top-left corner of the key in pixels, excluding the gap. - */ - public int getX() { - return mX; - } - - /** - * Gets the y-coordinate of the top-left corner of the key in pixels, excluding the gap. - * @return The y-coordinate of the top-left corner of the key in pixels, excluding the gap. - */ - public int getY() { - return mY; - } - - public final int getDrawX() { - final int x = getX(); - final OptionalAttributes attrs = mOptionalAttributes; - return (attrs == null) ? x : x + attrs.mVisualInsetsLeft; - } - - public final int getDrawWidth() { - final OptionalAttributes attrs = mOptionalAttributes; - return (attrs == null) ? mWidth - : mWidth - attrs.mVisualInsetsLeft - attrs.mVisualInsetsRight; + fun getPreviewIcon(iconSet: KeyboardIconsSet): Drawable? { + return iconSet.getIconDrawable(iconId) } /** * Informs the key that it has been pressed, in case it needs to change its appearance or * state. - * @see #onReleased() + * @see .onReleased */ - public void onPressed() { - mPressed = true; + fun onPressed() { + mPressed = true } /** * Informs the key that it has been released, in case it needs to change its appearance or * state. - * @see #onPressed() + * @see .onPressed */ - public void onReleased() { - mPressed = false; - } - - public final boolean isEnabled() { - return mEnabled; - } - - public void setEnabled(final boolean enabled) { - mEnabled = enabled; - } - - @Nonnull - public Rect getHitBox() { - return mHitBox; + fun onReleased() { + mPressed = false } /** @@ -1005,10 +448,10 @@ public class Key implements Comparable { * @param y the y-coordinate of the point * @return whether or not the point falls on the key. If the key is attached to an edge, it * will assume that all points between the key and the edge are considered to be on the key. - * @see #markAsLeftEdge(KeyboardParams) etc. + * @see .markAsLeftEdge */ - public boolean isOnKey(final int x, final int y) { - return mHitBox.contains(x, y); + fun isOnKey(x: Int, y: Int): Boolean { + return hitBox.contains(x, y) } /** @@ -1017,86 +460,89 @@ public class Key implements Comparable { * @param y the y-coordinate of the point * @return the square of the distance of the point from the nearest edge of the key */ - public int squaredDistanceToEdge(final int x, final int y) { - final int left = getX(); - final int right = left + mWidth; - final int top = getY(); - final int bottom = top + mHeight; - final int edgeX = x < left ? left : (x > right ? right : x); - final int edgeY = y < top ? top : (y > bottom ? bottom : y); - final int dx = x - edgeX; - final int dy = y - edgeY; - return dx * dx + dy * dy; + fun squaredDistanceToEdge(x: Int, y: Int): Int { + val left = this.x + val right = left + width + val top = this.y + val bottom = top + height + val edgeX = if (x < left) left else (if (x > right) right else x) + val edgeY = if (y < top) top else (if (y > bottom) bottom else y) + val dx = x - edgeX + val dy = y - edgeY + return dx * dx + dy * dy } - static class KeyBackgroundState { - private final int[] mReleasedState; - private final int[] mPressedState; + companion object { + @JvmStatic + fun removeRedundantMoreKeys( + key: Key, + lettersOnBaseLayout: LettersOnBaseLayout?, + onlyDuplicateKeys: Boolean + ): Key { + val moreKeys = key.moreKeys - private KeyBackgroundState(final int ... attrs) { - mReleasedState = attrs; - mPressedState = Arrays.copyOf(attrs, attrs.length + 1); - mPressedState[attrs.length] = android.R.attr.state_pressed; + var clearedMoreKeys: Array? + + clearedMoreKeys = MoreKeySpec.removeDuplicateMoreKeys(key.code, moreKeys.toTypedArray()) + + if (!onlyDuplicateKeys) { + clearedMoreKeys = MoreKeySpec.removeRedundantMoreKeys( + clearedMoreKeys, lettersOnBaseLayout!! + ) + } + + + val differs = when { + (moreKeys.isEmpty() && clearedMoreKeys == null) -> false + (moreKeys.isNotEmpty() && clearedMoreKeys != null) -> true + (clearedMoreKeys.contentEquals(moreKeys.toTypedArray())) -> false + else -> true + } + + return if(differs) { + key.copy( + moreKeys = clearedMoreKeys?.filterNotNull() ?: listOf() + ) + } else { + key + } } - public int[] getState(final boolean pressed) { - return pressed ? mPressedState : mReleasedState; + private fun needsToUpcase(labelFlags: Int, keyboardElementId: Int): Boolean { + if ((labelFlags and KeyConsts.LABEL_FLAGS_PRESERVE_CASE) != 0) return false + return when (keyboardElementId) { + KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED, KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED, KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED, KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED -> true + else -> false + } } - public static final KeyBackgroundState[] STATES = { - // 0: BACKGROUND_TYPE_EMPTY - new KeyBackgroundState(android.R.attr.state_empty), - // 1: BACKGROUND_TYPE_NORMAL - new KeyBackgroundState(), - // 2: BACKGROUND_TYPE_FUNCTIONAL - new KeyBackgroundState(android.R.attr.state_first), - // 3: BACKGROUND_TYPE_STICKY_OFF - new KeyBackgroundState(android.R.attr.state_checkable), - // 4: BACKGROUND_TYPE_STICKY_ON - new KeyBackgroundState(android.R.attr.state_checkable, android.R.attr.state_checked), - // 5: BACKGROUND_TYPE_ACTION - new KeyBackgroundState(android.R.attr.state_active), - // 6: BACKGROUND_TYPE_SPACEBAR - new KeyBackgroundState(), - }; - } + @JvmStatic + fun buildKeyForMoreKeySpec( + moreKeySpec: MoreKeySpec, + x: Int, + y: Int, + labelFlags: Int, + params: KeyboardParams + ): Key { + return Key( + code = moreKeySpec.mCode, + outputText = moreKeySpec.mOutputText, + label = moreKeySpec.mLabel ?: "", + iconId = moreKeySpec.mIconId ?: "", + hintLabel = null, + labelFlags = labelFlags, + visualStyle = KeyVisualStyle.MoreKey, + x = x, + y = y, + width = params.mDefaultKeyWidth, + height = params.mDefaultRowHeight, + horizontalGap = params.mHorizontalGap, + verticalGap = params.mVerticalGap, + actionFlags = KeyConsts.ACTION_FLAGS_NO_KEY_PREVIEW, - /** - * Returns the background drawable for the key, based on the current state and type of the key. - * @return the background drawable of the key. - * @see android.graphics.drawable.StateListDrawable#setState(int[]) - */ - @Nonnull - public final Drawable selectBackgroundDrawable(@Nonnull final Drawable keyBackground, - @Nonnull final Drawable functionalKeyBackground, - @Nonnull final Drawable spacebarBackground) { - final Drawable background; - if (mBackgroundType == BACKGROUND_TYPE_FUNCTIONAL) { - background = functionalKeyBackground; - } else if (mBackgroundType == BACKGROUND_TYPE_SPACEBAR) { - background = spacebarBackground; - } else { - background = keyBackground; - } - final int[] state = KeyBackgroundState.STATES[mBackgroundType].getState(mPressed); - background.setState(state); - return background; - } - - public static class Spacer extends Key { - public Spacer(final TypedArray keyAttr, final KeyStyle keyStyle, - final KeyboardParams params, final KeyboardRow row) { - super(null /* keySpec */, keyAttr, keyStyle, params, row); - } - - /** - * This constructor is being used only for divider in more keys keyboard. - */ - protected Spacer(final KeyboardParams params, final int x, final int y, final int width, - final int height) { - super(null /* label */, ICON_UNDEFINED, CODE_UNSPECIFIED, null /* outputText */, - null /* hintLabel */, 0 /* labelFlags */, BACKGROUND_TYPE_EMPTY, x, y, width, - height, params.mHorizontalGap, params.mVerticalGap, ACTION_FLAGS_NO_KEY_PREVIEW); + moreKeys = listOf(), + moreKeysColumnAndFlags = 0 + ) } } } diff --git a/java/src/org/futo/inputmethod/keyboard/KeyboardView.java b/java/src/org/futo/inputmethod/keyboard/KeyboardView.java index 3d5ca769e..e50db5a3b 100644 --- a/java/src/org/futo/inputmethod/keyboard/KeyboardView.java +++ b/java/src/org/futo/inputmethod/keyboard/KeyboardView.java @@ -94,9 +94,6 @@ public class KeyboardView extends View { private final float mKeyTextShadowRadius; private final float mVerticalCorrection; private final Drawable mKeyboardBackground; - private final Drawable mKeyBackground; - private final Drawable mFunctionalKeyBackground; - private final Drawable mSpacebarBackground; protected final DynamicThemeProvider mDrawableProvider; private final float mSpacebarIconWidthRatio; private final Rect mKeyBackgroundPadding = new Rect(); @@ -155,20 +152,10 @@ public class KeyboardView extends View { boolean isMoreKeys = keyAttr.getBoolean(R.styleable.Keyboard_Key_isMoreKey, false); boolean isMoreKeysAction = keyAttr.getBoolean(R.styleable.Keyboard_Key_isAction, false); - mKeyboardBackground = isMoreKeysAction ? null : - isMoreKeys ? mDrawableProvider.getMoreKeysKeyboardBackground() : + mKeyboardBackground = isMoreKeys ? mDrawableProvider.getMoreKeysKeyboardBackground() : mDrawableProvider.getKeyboardBackground(); setBackground(mKeyboardBackground); - mKeyBackground = isMoreKeysAction ? mDrawableProvider.getActionPopupKey() : - isMoreKeys ? mDrawableProvider.getPopupKey() : - mDrawableProvider.getKeyBackground(); - mKeyBackground.getPadding(mKeyBackgroundPadding); - - mFunctionalKeyBackground = mKeyBackground; - - mSpacebarBackground = mDrawableProvider.getSpaceBarBackground(); - mSpacebarIconWidthRatio = keyboardViewAttr.getFloat( R.styleable.KeyboardView_spacebarIconWidthRatio, 1.0f); mKeyHintLetterPadding = keyboardViewAttr.getDimension( @@ -372,12 +359,9 @@ public class KeyboardView extends View { Math.min(key.getHeight(), key.getWidth()), attr); params.mAnimAlpha = Constants.Color.ALPHA_OPAQUE; - if (!key.isSpacer()) { - final Drawable background = key.selectBackgroundDrawable( - mKeyBackground, mFunctionalKeyBackground, mSpacebarBackground); - if (background != null) { - onDrawKeyBackground(key, canvas, background); - } + final Drawable background = key.selectBackground(mDrawableProvider); + if (background != null) { + onDrawKeyBackground(key, canvas, background); } onDrawKeyTopVisuals(key, canvas, paint, params); @@ -392,13 +376,15 @@ public class KeyboardView extends View { final int bgWidth, bgHeight, bgX, bgY; if (key.needsToKeepBackgroundAspectRatio(mDefaultKeyLabelFlags) // HACK: To disable expanding normal/functional key background. - && !key.hasCustomActionLabel()) { + && !key.getHasCustomActionLabel()) { bgWidth = Math.min(keyWidth, keyHeight); bgHeight = Math.min(keyWidth, keyHeight); bgX = (keyWidth - bgWidth) / 2; bgY = (keyHeight - bgHeight) / 2; } else { - final Rect padding = mKeyBackgroundPadding; + final Rect padding = new Rect(); + background.getPadding(padding); + bgWidth = keyWidth + padding.left + padding.right; bgHeight = keyHeight + padding.top + padding.bottom; bgX = -padding.left; @@ -448,10 +434,10 @@ public class KeyboardView extends View { labelX = centerX; paint.setTextAlign(Align.CENTER); } - if (key.needsAutoXScale()) { + if (key.getNeedsAutoXScale()) { final float ratio = Math.min(1.0f, (keyWidth * MAX_LABEL_RATIO) / TypefaceUtils.getStringWidth(label, paint)); - if (key.needsAutoScale()) { + if (key.getNeedsAutoScale()) { final float autoSize = paint.getTextSize() * ratio; paint.setTextSize(autoSize); } else { @@ -460,7 +446,7 @@ public class KeyboardView extends View { } if (key.isEnabled()) { - paint.setColor(key.selectTextColor(params)); + paint.setColor(key.selectTextColor(mDrawableProvider, params)); // Set a drop shadow for the text if the shadow radius is positive value. if (mKeyTextShadowRadius > 0.0f) { paint.setShadowLayer(mKeyTextShadowRadius, 0.0f, 0.0f, params.mTextShadowColor); @@ -480,17 +466,17 @@ public class KeyboardView extends View { } // Draw hint label. - final String hintLabel = key.getHintLabel(); + final String hintLabel = key.getEffectiveHintLabel(); if (hintLabel != null) { - paint.setTextSize(key.selectHintTextSize(params)); - paint.setColor(key.selectHintTextColor(params)); + paint.setTextSize(key.selectHintTextSize(mDrawableProvider, params)); + paint.setColor(key.selectHintTextColor(mDrawableProvider, params)); // TODO: Should add a way to specify type face for hint letters paint.setTypeface(Typeface.DEFAULT); blendAlpha(paint, params.mAnimAlpha); final float labelCharHeight = TypefaceUtils.getReferenceCharHeight(paint); final float labelCharWidth = TypefaceUtils.getReferenceCharWidth(paint); final float hintX, hintBaseline; - if (key.hasHintLabel()) { + if (key.getHasHintLabel()) { // The hint label is placed just right of the key label. Used mainly on // "phone number" layout. hintX = labelX + params.mHintLabelOffCenterRatio * labelCharWidth; @@ -500,7 +486,7 @@ public class KeyboardView extends View { hintBaseline = centerY + labelCharHeight / 2.0f; } paint.setTextAlign(Align.CENTER); - } else if (key.hasShiftedLetterHint()) { + } else if (key.getHasShiftedLetterHint()) { // The hint label is placed at top-right corner of the key. Used mainly on tablet. hintX = keyWidth - mKeyShiftedLetterHintPadding - labelCharWidth / 2.0f; paint.getFontMetrics(mFontMetrics); @@ -519,7 +505,7 @@ public class KeyboardView extends View { canvas.drawText( hintLabel, 0, hintLabel.length(), hintX, hintBaseline + adjustmentY, paint); } else if(hintIcon != null) { - final float size = key.selectHintTextSize(params); + final float size = key.selectHintTextSize(mDrawableProvider, params); int iconWidth = (int)size; int iconHeight = (int)size; @@ -527,7 +513,7 @@ public class KeyboardView extends View { int hintX = keyWidth - iconWidth - (int)mKeyHintLetterPadding; int hintY = (int)mKeyHintLetterPadding; - hintIcon.setTint(key.selectHintTextColor(params)); + hintIcon.setTint(key.selectHintTextColor(mDrawableProvider, params)); drawIcon(canvas, hintIcon, hintX, hintY, iconWidth, iconHeight); } @@ -556,11 +542,11 @@ public class KeyboardView extends View { } final int iconX = (keyWidth - iconWidth) / 2; // Align horizontally center. - icon.setTint(key.selectTextColor(params)); + icon.setTint(key.selectTextColor(mDrawableProvider, params)); drawIcon(canvas, icon, iconX, iconY, iconWidth, iconHeight); } - if (key.hasPopupHint() && key.getMoreKeys() != null) { + if (key.getHasPopupHint() && !key.getMoreKeys().isEmpty()) { drawKeyPopupHint(key, canvas, paint, params); } } @@ -599,7 +585,7 @@ public class KeyboardView extends View { paint.setTypeface(mKeyDrawParams.mTypeface); paint.setTextSize(mKeyDrawParams.mLabelSize); } else { - paint.setColor(key.selectTextColor(mKeyDrawParams)); + paint.setColor(key.selectTextColor(mDrawableProvider, mKeyDrawParams)); paint.setTypeface(key.selectTypeface(mKeyDrawParams)); paint.setTextSize(key.selectTextSize(mKeyDrawParams)); } diff --git a/java/src/org/futo/inputmethod/keyboard/MainKeyboardView.java b/java/src/org/futo/inputmethod/keyboard/MainKeyboardView.java index 13a80fe6a..0e5cef40d 100644 --- a/java/src/org/futo/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/org/futo/inputmethod/keyboard/MainKeyboardView.java @@ -58,6 +58,7 @@ import org.futo.inputmethod.latin.common.CoordinateUtils; import org.futo.inputmethod.latin.utils.LanguageOnSpacebarUtils; import org.futo.inputmethod.latin.utils.TypefaceUtils; +import java.util.List; import java.util.Locale; import java.util.WeakHashMap; @@ -150,7 +151,6 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy // More keys keyboard private final Paint mBackgroundDimAlphaPaint = new Paint(); private final View mMoreKeysKeyboardContainer; - private final View mMoreKeysKeyboardForActionContainer; private final WeakHashMap mMoreKeysKeyboardCache = new WeakHashMap<>(); private final boolean mConfigShowMoreKeysKeyboardAtTouchedPoint; // More keys panel (used by both more keys keyboard and more suggestions view) @@ -234,9 +234,6 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy final int moreKeysKeyboardLayoutId = mainKeyboardViewAttr.getResourceId( R.styleable.MainKeyboardView_moreKeysKeyboardLayout, 0); - final int moreKeysKeyboardForActionLayoutId = mainKeyboardViewAttr.getResourceId( - R.styleable.MainKeyboardView_moreKeysKeyboardForActionLayout, - moreKeysKeyboardLayoutId); mConfigShowMoreKeysKeyboardAtTouchedPoint = mainKeyboardViewAttr.getBoolean( R.styleable.MainKeyboardView_showMoreKeysKeyboardAtTouchedPoint, false); @@ -258,8 +255,6 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy final LayoutInflater inflater = LayoutInflater.from(getContext()); mMoreKeysKeyboardContainer = inflater.inflate(moreKeysKeyboardLayoutId, null); - mMoreKeysKeyboardForActionContainer = inflater.inflate( - moreKeysKeyboardForActionLayoutId, null); mLanguageOnSpacebarFadeoutAnimator = loadObjectAnimator( languageOnSpacebarFadeoutAnimatorResId, this); mAltCodeKeyWhileTypingFadeoutAnimator = loadObjectAnimator( @@ -468,7 +463,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy public void onKeyPressed(@Nonnull final Key key, final boolean withPreview) { key.onPressed(); invalidateKey(key); - if (withPreview && !key.noKeyPreview()) { + if (withPreview && !key.getNoKeyPreview()) { showKeyPreview(key); } } @@ -500,7 +495,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy public void onKeyReleased(@Nonnull final Key key, final boolean withAnimation) { key.onReleased(); invalidateKey(key); - if (!key.noKeyPreview()) { + if (!key.getNoKeyPreview()) { if (withAnimation) { dismissKeyPreview(key); } else { @@ -597,8 +592,8 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy @Nullable public MoreKeysPanel showMoreKeysKeyboard(@Nonnull final Key key, @Nonnull final PointerTracker tracker) { - final MoreKeySpec[] moreKeys = key.getMoreKeys(); - if (moreKeys == null) { + final List moreKeys = key.getMoreKeys(); + if (moreKeys.isEmpty()) { return null; } Keyboard moreKeysKeyboard = mMoreKeysKeyboardCache.get(key); @@ -609,7 +604,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy // will cause zero-division error at // {@link MoreKeysKeyboardParams#setParameters(int,int,int,int,int,int,boolean,int)}. final boolean isSingleMoreKeyWithPreview = mKeyPreviewDrawParams.isPopupEnabled() - && !key.noKeyPreview() && moreKeys.length == 1 + && !key.getNoKeyPreview() && moreKeys.size() == 1 && mKeyPreviewDrawParams.getVisibleWidth() > 0; final MoreKeysKeyboard.Builder builder = new MoreKeysKeyboard.Builder( getContext(), key, getKeyboard(), isSingleMoreKeyWithPreview, @@ -619,8 +614,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy mMoreKeysKeyboardCache.put(key, moreKeysKeyboard); } - final View container = key.isActionKey() ? mMoreKeysKeyboardForActionContainer - : mMoreKeysKeyboardContainer; + final View container = mMoreKeysKeyboardContainer; final MoreKeysKeyboardView moreKeysKeyboardView = (MoreKeysKeyboardView)container.findViewById(R.id.more_keys_keyboard_view); moreKeysKeyboardView.setKeyboard(moreKeysKeyboard); @@ -628,8 +622,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy final int[] lastCoords = CoordinateUtils.newInstance(); tracker.getLastCoordinates(lastCoords); - final boolean keyPreviewEnabled = mKeyPreviewDrawParams.isPopupEnabled() - && !key.noKeyPreview(); + final boolean keyPreviewEnabled = mKeyPreviewDrawParams.isPopupEnabled(); // The more keys keyboard is usually horizontally aligned with the center of the parent key. // If showMoreKeysKeyboardAtTouchedPoint is true and the key preview is disabled, the more // keys keyboard is placed at the touch point of the parent key. @@ -776,16 +769,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy } public void updateShortcutKey(final boolean available) { - final Keyboard keyboard = getKeyboard(); - if (keyboard == null) { - return; - } - final Key shortcutKey = keyboard.getKey(Constants.CODE_SHORTCUT); - if (shortcutKey == null) { - return; - } - shortcutKey.setEnabled(available); - invalidateKey(shortcutKey); + // TODO: Remove } public void startDisplayLanguageOnSpacebar(final boolean subtypeChanged, @@ -819,7 +803,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy @Override protected void onDrawKeyTopVisuals(final Key key, final Canvas canvas, final Paint paint, final KeyDrawParams params) { - if (key.altCodeWhileTyping() && key.isEnabled()) { + if (key.getAltCodeWhileTyping() && key.isEnabled()) { params.mAnimAlpha = mAltCodeKeyWhileTypingAnimAlpha; } super.onDrawKeyTopVisuals(key, canvas, paint, params); diff --git a/java/src/org/futo/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/org/futo/inputmethod/keyboard/MoreKeysKeyboard.java index ee44fbbad..7b8dea41b 100644 --- a/java/src/org/futo/inputmethod/keyboard/MoreKeysKeyboard.java +++ b/java/src/org/futo/inputmethod/keyboard/MoreKeysKeyboard.java @@ -27,6 +27,8 @@ import org.futo.inputmethod.latin.R; import org.futo.inputmethod.latin.common.StringUtils; import org.futo.inputmethod.latin.utils.TypefaceUtils; +import java.util.List; + import javax.annotation.Nonnull; public final class MoreKeysKeyboard extends Keyboard { @@ -299,19 +301,16 @@ public final class MoreKeysKeyboard extends Keyboard { } else { final float padding = context.getResources().getDimension( R.dimen.config_more_keys_keyboard_key_horizontal_padding) - + (key.hasLabelsInMoreKeys() + + (key.getHasLabelsInMoreKeys() ? mParams.mDefaultKeyWidth * LABEL_PADDING_RATIO : 0.0f); - keyWidth = getMaxKeyWidth(key, mParams.mDefaultKeyWidth, padding, paintToMeasure); - rowHeight = keyboard.mMostCommonKeyHeight; + + int dimension = (int)(context.getResources().getDisplayMetrics().density * 44.5f); + keyWidth = getMaxKeyWidth(key, Math.min(dimension, key.getTotalWidth()), padding, paintToMeasure); + rowHeight = dimension; } - final int dividerWidth; - if (key.needsDividersInMoreKeys()) { - dividerWidth = (int)(keyWidth * DIVIDER_RATIO); - } else { - dividerWidth = 0; - } - final MoreKeySpec[] moreKeys = key.getMoreKeys(); - mParams.setParameters(moreKeys.length, key.getMoreKeysColumnNumber(), keyWidth, + final int dividerWidth = 0; // TODO: Remove divider + final List moreKeys = key.getMoreKeys(); + mParams.setParameters(moreKeys.size(), key.getMoreKeysColumnNumber(), keyWidth, rowHeight, key.getX() + key.getWidth() / 2, keyboard.mId.mWidth, key.isMoreKeysFixedColumn(), key.isMoreKeysFixedOrder(), dividerWidth); } @@ -335,36 +334,18 @@ public final class MoreKeysKeyboard extends Keyboard { public MoreKeysKeyboard build() { final MoreKeysKeyboardParams params = mParams; final int moreKeyFlags = mParentKey.getMoreKeyLabelFlags(); - final MoreKeySpec[] moreKeys = mParentKey.getMoreKeys(); - for (int n = 0; n < moreKeys.length; n++) { - final MoreKeySpec moreKeySpec = moreKeys[n]; + final List moreKeys = mParentKey.getMoreKeys(); + for (int n = 0; n < moreKeys.size(); n++) { + final MoreKeySpec moreKeySpec = moreKeys.get(n); final int row = n / params.mNumColumns; final int x = params.getX(n, row); final int y = params.getY(row); final Key key = moreKeySpec.buildKey(x, y, moreKeyFlags, params); params.markAsEdgeKey(key, row); params.onAddKey(key); - - final int pos = params.getColumnPos(n); - // The "pos" value represents the offset from the default position. Negative means - // left of the default position. - if (params.mDividerWidth > 0 && pos != 0) { - final int dividerX = (pos > 0) ? x - params.mDividerWidth - : x + params.mDefaultKeyWidth; - final Key divider = new MoreKeyDivider( - params, dividerX, y, params.mDividerWidth, params.mDefaultRowHeight); - params.onAddKey(divider); - } } return new MoreKeysKeyboard(params); } } - // Used as a divider maker. A divider is drawn by {@link MoreKeysKeyboardView}. - public static class MoreKeyDivider extends Key.Spacer { - public MoreKeyDivider(final KeyboardParams params, final int x, final int y, - final int width, final int height) { - super(params, x, y, width, height); - } - } } diff --git a/java/src/org/futo/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/org/futo/inputmethod/keyboard/MoreKeysKeyboardView.java index d30b27e51..475a7c9ef 100644 --- a/java/src/org/futo/inputmethod/keyboard/MoreKeysKeyboardView.java +++ b/java/src/org/futo/inputmethod/keyboard/MoreKeysKeyboardView.java @@ -88,8 +88,7 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel @Override protected void onDrawKeyTopVisuals(final Key key, final Canvas canvas, final Paint paint, final KeyDrawParams params) { - if (!key.isSpacer() || !(key instanceof MoreKeysKeyboard.MoreKeyDivider) - || mDivider == null) { + if (!key.isSpacer() || mDivider == null) { super.onDrawKeyTopVisuals(key, canvas, paint, params); return; } diff --git a/java/src/org/futo/inputmethod/keyboard/PointerTracker.java b/java/src/org/futo/inputmethod/keyboard/PointerTracker.java index 26d810bcf..a69fa9397 100644 --- a/java/src/org/futo/inputmethod/keyboard/PointerTracker.java +++ b/java/src/org/futo/inputmethod/keyboard/PointerTracker.java @@ -291,7 +291,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element, private void callListenerOnCodeInput(final Key key, final int primaryCode, final int x, final int y, final long eventTime, final boolean isKeyRepeat) { final boolean ignoreModifierKey = mIsInDraggingFinger && key.isModifier(); - final boolean altersCode = key.altCodeWhileTyping() && sTimerProxy.isTypingState(); + final boolean altersCode = key.getAltCodeWhileTyping() && sTimerProxy.isTypingState(); final int code = altersCode ? key.getAltCode() : primaryCode; if (DEBUG_LISTENER) { final String output = code == Constants.CODE_OUTPUT_TEXT @@ -412,7 +412,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element, } } - if (key.altCodeWhileTyping()) { + if (key.getAltCodeWhileTyping()) { final int altCode = key.getAltCode(); final Key altKey = mKeyboard.getKey(altCode); if (altKey != null) { @@ -437,7 +437,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element, } // Even if the key is disabled, it should respond if it is in the altCodeWhileTyping state. - final boolean altersCode = key.altCodeWhileTyping() && sTimerProxy.isTypingState(); + final boolean altersCode = key.getAltCodeWhileTyping() && sTimerProxy.isTypingState(); final boolean needsToUpdateGraphics = key.isEnabled() || altersCode; if (!needsToUpdateGraphics) { return; @@ -1106,9 +1106,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element, if (key == null) { return; } - if (key.hasNoPanelAutoMoreKey()) { + if (key.getHasNoPanelAutoMoreKey()) { cancelKeyTracking(); - final int moreKeyCode = key.getMoreKeys()[0].mCode; + final int moreKeyCode = key.getMoreKeys().get(0).mCode; sListener.onPressKey(moreKeyCode, 0 /* repeatCont */, true /* isSinglePointer */); sListener.onCodeInput(moreKeyCode, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false /* isKeyRepeat */); diff --git a/java/src/org/futo/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/org/futo/inputmethod/keyboard/internal/KeyboardBuilder.java index 941d3299b..517bdbd03 100644 --- a/java/src/org/futo/inputmethod/keyboard/internal/KeyboardBuilder.java +++ b/java/src/org/futo/inputmethod/keyboard/internal/KeyboardBuilder.java @@ -46,7 +46,6 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; -import java.util.Arrays; import java.util.Locale; import javax.annotation.Nonnull; @@ -121,7 +120,7 @@ import javax.annotation.Nonnull; * */ -// TODO: Write unit tests for this class. +// TODO: Remove this class, XML is no longer used for building keyboards public class KeyboardBuilder { private static final String BUILDER_TAG = "Keyboard.Builder"; private static final boolean DEBUG = false; @@ -490,10 +489,10 @@ public class KeyboardBuilder { final int y = row.getKeyY(); final int width = (int)keyWidth; final int height = row.getRowHeight(); - final Key key = new Key(label, KeyboardIconsSet.ICON_UNDEFINED, code, outputText, - null /* hintLabel */, labelFlags, backgroundType, x, y, width, height, - mParams.mHorizontalGap, mParams.mVerticalGap, Key.ACTION_FLAGS_NO_KEY_PREVIEW); - endKey(key); + //final Key key = new Key(label, KeyboardIconsSet.ICON_UNDEFINED, code, outputText, + // null /* hintLabel */, labelFlags, backgroundType, x, y, width, height, + // mParams.mHorizontalGap, mParams.mVerticalGap, KeyConsts.ACTION_FLAGS_NO_KEY_PREVIEW); + //endKey(key); row.advanceXPos(keyWidth); } endRow(row); @@ -516,14 +515,14 @@ public class KeyboardBuilder { if (TextUtils.isEmpty(keySpec)) { throw new ParseException("Empty keySpec", parser); } - final Key key = new Key(keySpec, keyAttr, keyStyle, mParams, row); + //final Key key = new Key(keySpec, keyAttr, keyStyle, mParams, row); keyAttr.recycle(); - if (DEBUG) { - startEndTag("<%s%s %s moreKeys=%s />", TAG_KEY, (key.isEnabled() ? "" : " disabled"), - key, Arrays.toString(key.getMoreKeys())); - } + //if (DEBUG) { + // startEndTag("<%s%s %s moreKeys=%s />", TAG_KEY, (key.isEnabled() ? "" : " disabled"), + // key, Arrays.toString(key.getMoreKeys())); + //} XmlParseUtils.checkEndTag(TAG_KEY, parser); - endKey(key); + //endKey(key); } private void parseSpacer(final XmlPullParser parser, final KeyboardRow row, final boolean skip) @@ -536,11 +535,11 @@ public class KeyboardBuilder { final TypedArray keyAttr = mResources.obtainAttributes( Xml.asAttributeSet(parser), R.styleable.Keyboard_Key); final KeyStyle keyStyle = mParams.mKeyStyles.getKeyStyle(keyAttr, parser); - final Key spacer = new Key.Spacer(keyAttr, keyStyle, mParams, row); + //final Key spacer = new Key.Spacer(keyAttr, keyStyle, mParams, row); keyAttr.recycle(); if (DEBUG) startEndTag("<%s />", TAG_SPACER); XmlParseUtils.checkEndTag(TAG_SPACER, parser); - endKey(spacer); + //endKey(spacer); } private void parseIncludeKeyboardContent(final XmlPullParser parser, final boolean skip) diff --git a/java/src/org/futo/inputmethod/keyboard/internal/KeyboardParams.java b/java/src/org/futo/inputmethod/keyboard/internal/KeyboardParams.java index 093eef34b..4185c6e0a 100644 --- a/java/src/org/futo/inputmethod/keyboard/internal/KeyboardParams.java +++ b/java/src/org/futo/inputmethod/keyboard/internal/KeyboardParams.java @@ -133,7 +133,7 @@ public class KeyboardParams { if (key.getCode() == Constants.CODE_SHIFT) { mShiftKeys.add(key); } - if (key.altCodeWhileTyping()) { + if (key.getAltCodeWhileTyping()) { mAltCodeKeysWhileTyping.add(key); } } diff --git a/java/src/org/futo/inputmethod/keyboard/internal/KeyboardRow.java b/java/src/org/futo/inputmethod/keyboard/internal/KeyboardRow.java index de16a50e3..e2c181dd6 100644 --- a/java/src/org/futo/inputmethod/keyboard/internal/KeyboardRow.java +++ b/java/src/org/futo/inputmethod/keyboard/internal/KeyboardRow.java @@ -20,7 +20,7 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.util.Xml; -import org.futo.inputmethod.keyboard.Key; +import org.futo.inputmethod.keyboard.KeyConsts; import org.futo.inputmethod.keyboard.Keyboard; import org.futo.inputmethod.latin.R; import org.futo.inputmethod.latin.utils.ResourceUtils; @@ -34,6 +34,7 @@ import java.util.ArrayDeque; * Some of the key size defaults can be overridden per row from what the {@link Keyboard} * defines. */ +// TODO: Remove this class, it is no longer used public final class KeyboardRow { // keyWidth enum constants private static final int KEYWIDTH_NOT_ENUM = 0; @@ -67,7 +68,7 @@ public final class KeyboardRow { keyboardWidth, keyboardWidth, defaultKeyWidth); mDefaultKeyLabelFlags = keyAttr.getInt(R.styleable.Keyboard_Key_keyLabelFlags, 0); mDefaultBackgroundType = keyAttr.getInt(R.styleable.Keyboard_Key_backgroundType, - Key.BACKGROUND_TYPE_NORMAL); + KeyConsts.BACKGROUND_TYPE_NORMAL); } /** diff --git a/java/src/org/futo/inputmethod/keyboard/internal/KeyboardTextsTable.java b/java/src/org/futo/inputmethod/keyboard/internal/KeyboardTextsTable.java index 5d9f2782e..5cfbba0f3 100644 --- a/java/src/org/futo/inputmethod/keyboard/internal/KeyboardTextsTable.java +++ b/java/src/org/futo/inputmethod/keyboard/internal/KeyboardTextsTable.java @@ -79,8 +79,8 @@ public final class KeyboardTextsTable { // /* index:histogram */ "name", "locale", "keylabel_to_alpha", - "morekeys_a", "morekeys_o", + "morekeys_a", "morekeys_u", "morekeys_e", "morekeys_i", @@ -89,284 +89,284 @@ public final class KeyboardTextsTable { "morekeys_c", "keyspec_currency", "morekeys_s", - "morekeys_misc_o", "morekeys_misc_a", + "morekeys_misc_o", "morekeys_misc_u", "morekeys_misc_e", - "morekeys_misc_i", "morekeys_z", "morekeys_n", - "morekeys_misc_s", + "morekeys_misc_i", "morekeys_misc_c", + "morekeys_misc_s", "double_angle_quotes", "single_angle_quotes", "morekeys_y", - "additional_morekeys_symbols_8", - "additional_morekeys_symbols_6", - "morekeys_d", "keyspec_symbols_9", - "morekeys_misc_z", - "additional_morekeys_symbols_9", - "keyspec_symbols_5", - "keyspec_symbols_4", - "additional_morekeys_symbols_3", - "morekeys_g", - "additional_morekeys_symbols_1", - "keyspec_symbols_7", "keyspec_symbols_8", - "keyspec_symbols_6", - "keyspec_symbols_3", - "additional_morekeys_symbols_4", + "additional_morekeys_symbols_9", "additional_morekeys_symbols_5", - "additional_morekeys_symbols_0", - "additional_morekeys_symbols_2", - "additional_morekeys_symbols_7", + "keyspec_symbols_5", + "keyspec_symbols_3", + "keyspec_symbols_6", "keyspec_symbols_1", + "morekeys_g", + "additional_morekeys_symbols_0", + "keyspec_symbols_4", + "additional_morekeys_symbols_7", + "additional_morekeys_symbols_6", + "morekeys_misc_z", + "additional_morekeys_symbols_2", + "morekeys_d", + "additional_morekeys_symbols_8", + "additional_morekeys_symbols_3", "keyspec_symbols_2", + "keyspec_symbols_7", "keyspec_symbols_0", - "keylabel_to_symbol", + "additional_morekeys_symbols_4", + "additional_morekeys_symbols_1", "morekeys_cyrillic_ie", + "keylabel_to_symbol", "morekeys_tablet_period", + "keyspec_east_slavic_row2_2", + "keyspec_nordic_row2_11", "morekeys_period", - "morekeys_nordic_row2_10", - "keyspec_east_slavic_row3_5", - "keyspec_tablet_comma", - "keyspec_east_slavic_row1_9", "morekeys_misc_n", "keyspec_nordic_row2_10", - "keyspec_east_slavic_row2_2", - "morekeys_cyrillic_soft_sign", - "keyspec_nordic_row2_11", - "keyspec_east_slavic_row2_11", + "keyspec_east_slavic_row1_9", + "keyspec_tablet_comma", + "keyspec_east_slavic_row3_5", "keyspec_period", - "keyspec_nordic_row1_11", + "morekeys_nordic_row2_10", "morekeys_t", + "morekeys_cyrillic_soft_sign", + "keyspec_east_slavic_row2_11", + "keyspec_nordic_row1_11", "keyspec_less_than", "morekeys_tablet_comma", - "keyspec_left_single_angle_quote", - "morekeys_l", - "keyspec_left_curly_bracket", - "morekeys_r", - "keyspec_right_square_bracket", - "keyspec_right_parenthesis", - "keyspec_left_double_angle_quote", "keyspec_less_than_equal", - "keyspec_left_square_bracket", - "keyspec_greater_than", - "keyspec_right_curly_bracket", - "keyspec_comma", + "keyspec_right_parenthesis", "keyspec_left_parenthesis", - "morekeys_star", - "morekeys_punctuation", - "morekeys_nordic_row2_11", - "keyhintlabel_period", - "morekeys_question", "keyspec_right_double_angle_quote", + "keyspec_right_square_bracket", + "keyhintlabel_period", + "morekeys_r", + "keyspec_left_square_bracket", + "morekeys_punctuation", + "keyspec_comma", + "morekeys_l", "keyspec_greater_than_equal", + "morekeys_star", + "keyspec_right_curly_bracket", + "keyspec_left_single_angle_quote", "keyspec_tablet_period", + "morekeys_question", + "keyspec_left_curly_bracket", + "keyspec_left_double_angle_quote", + "morekeys_nordic_row2_11", + "keyspec_greater_than", "keyspec_right_single_angle_quote", - "keyspec_symbols_percent", - "keyspec_swiss_row2_11", + "morekeys_misc_y", + "keyspec_swiss_row1_11", "morekeys_bullet", - "keyspec_swiss_row2_10", "morekeys_swiss_row1_11", - "morekeys_arabic_diacritics", - "keyspec_symbols_question", - "keyspec_spanish_row2_10", - "morekeys_swiss_row2_10", "morekeys_symbols_semicolon", + "keyspec_swiss_row2_11", + "keyhintlabel_tablet_period", + "keyspec_swiss_row2_10", + "keyspec_symbols_question", "morekeys_right_parenthesis", "morekeys_symbols_percent", "morekeys_left_parenthesis", - "keyhintlabel_tablet_comma", + "keyspec_spanish_row2_10", "keyspec_symbols_semicolon", - "keyhintlabel_tablet_period", + "keyspec_symbols_percent", + "keyhintlabel_tablet_comma", "morekeys_swiss_row2_11", - "morekeys_misc_y", - "keyspec_swiss_row1_11", - "keyspec_south_slavic_row3_8", - "morekeys_misc_r", - "keyspec_south_slavic_row2_11", - "label_send_key", - "morekeys_misc_g", - "morekeys_cyrillic_u", - "morekeys_k", - "morekeys_misc_l", + "morekeys_swiss_row2_10", + "morekeys_arabic_diacritics", "morekeys_cyrillic_en", - "morekeys_cyrillic_i", - "morekeys_tablet_punctuation", - "morekeys_cyrillic_ghe", - "morekeys_cyrillic_o", - "label_previous_key", - "keyspec_south_slavic_row1_6", - "label_next_key", "label_wait_key", - "label_pause_key", - "morekeys_h", - "morekeys_east_slavic_row2_2", + "morekeys_misc_g", + "label_previous_key", + "label_search_key", + "keyspec_south_slavic_row2_11", + "morekeys_misc_l", + "label_done_key", "keyspec_south_slavic_row3_1", "label_go_key", - "label_done_key", - "label_search_key", - "morekeys_j", - "keyspec_q", + "morekeys_misc_r", + "morekeys_cyrillic_ghe", + "label_pause_key", + "morekeys_tablet_punctuation", + "morekeys_k", + "keyspec_south_slavic_row3_8", + "label_next_key", + "label_send_key", + "morekeys_cyrillic_u", + "morekeys_cyrillic_o", + "morekeys_cyrillic_i", + "keyspec_south_slavic_row1_6", + "morekeys_h", + "morekeys_east_slavic_row2_2", "keyspec_y", - "morekeys_currency_dollar", - "morekeys_less_than", - "morekeys_exclamation", - "keyspec_x", - "morekeys_cyrillic_a", - "morekeys_w", - "morekeys_misc_t", - "keyspec_w", - "morekeys_cyrillic_ka", "morekeys_misc_h", + "morekeys_w", + "morekeys_cyrillic_a", "morekeys_east_slavic_row2_11", - "morekeys_greater_than", + "keyspec_q", + "keyspec_x", + "morekeys_j", + "morekeys_exclamation", "morekeys_plus", - "actions_j", - "qwertysyms_b", - "actions_y", - "actions_u", - "qwertysyms_v", - "morekeys_misc_q", - "qwertysyms_0", - "morekeys_p", - "morekeys_misc_x", - "qwertysyms_p", - "actions_n", - "single_9qm_lqm", - "morekeys_misc_f", - "actions_t", - "single_9qm_rqm", - "qwertysyms_i", - "qwertysyms_w", - "morekeys_v", - "qwertysyms_2", - "number_5", - "morekeys_misc_v", - "actions_x", - "double_lqm_rqm", - "qwertysyms_m", - "morekeys_misc_m", - "actions_2", - "morekeys_misc_w", - "single_raqm_laqm", - "actions_4", - "morekeys_misc_d", - "double_laqm_raqm", - "morekeys_currency_generic", - "number_7", - "actions_d", - "qwertysyms_6", - "qwertysyms_n", - "number_6", - "number_3", - "morekeys_symbols_8", - "actions_7", - "qwertysyms_9", - "qwertysyms_k", - "qwertysyms_c", - "actions_5", - "keyspecs_left_parenthesis_more_keys", - "single_lqm_rqm", - "single_rqm_9qm", - "keyspec_emoji_action_key_navigation", - "qwertysyms_q", - "morekeys_am_pm", - "keylabel_to_phone_numeric", - "morekeys_misc_j", - "keyspec_popular_domain", - "keylabel_tablet_to_more_symbol", - "actions_m", - "qwertysyms_f", - "actions_f", - "morekeys_double_quote", - "number_4", - "keylabel_to_more_symbol", - "double_9qm_rqm", - "morekeys_q", - "qwertysyms_r", - "morekeys_symbols_5", - "qwertysyms_o", - "keylabel_time_am", - "morekeys_symbols_6", - "qwertysyms_h", - "keyspec_action_next", - "actions_6", - "qwertysyms_3", - "morekeys_symbols_4", - "morekeys_symbols_9", - "qwertysyms_y", - "actions_h", - "qwertysyms_a", - "actions_a", - "qwertysyms_s", - "keyspec_emoji_action_key", - "actions_b", - "keyspecs_right_parenthesis_more_keys", - "actions_0", - "actions_w", - "keyspec_shortcut", - "morekeys_x", - "keylabel_to_phone_symbols", - "morekeys_misc_p", - "morekeys_popular_domain", - "qwertysyms_7", - "keyspec_action_previous", - "morekeys_misc_k", - "qwertysyms_8", - "number_0", - "actions_i", - "morekeys_b", - "qwertysyms_5", - "actions_p", - "morekeys_misc_b", - "actions_8", - "double_9qm_lqm", - "actions_g", - "number_1", - "actions_k", - "keyspec_settings", - "qwertysyms_u", - "double_raqm_laqm", - "morekeys_single_quote", - "morekeys_symbols_3", - "qwertysyms_e", - "actions_r", - "actions_l", - "number_2", - "number_8", - "single_laqm_raqm", - "actions_z", - "morekeys_symbols_1", - "morekeys_symbols_2", - "qwertysyms_4", - "morekeys_symbols_0", - "qwertysyms_d", - "actions_c", - "qwertysyms_l", - "qwertysyms_z", - "actions_3", - "actions_v", - "qwertysyms_g", - "qwertysyms_1", - "actions_9", - "actions_q", - "morekeys_f", + "keyspec_w", + "morekeys_less_than", + "morekeys_greater_than", + "morekeys_currency_dollar", + "morekeys_misc_t", + "morekeys_cyrillic_ka", "morekeys_m", - "double_rqm_9qm", - "qwertysyms_x", - "morekeys_symbols_7", - "actions_s", - "qwertysyms_t", - "number_9", - "actions_e", - "actions_o", - "qwertysyms_j", + "actions_h", + "keyspec_action_next", + "qwertysyms_4", + "qwertysyms_8", + "actions_u", + "morekeys_misc_d", + "morekeys_popular_domain", + "single_9qm_lqm", + "qwertysyms_1", + "actions_2", + "qwertysyms_e", + "actions_9", + "actions_t", + "actions_a", + "actions_l", + "morekeys_misc_q", + "morekeys_x", + "morekeys_misc_m", + "number_1", + "actions_w", + "morekeys_misc_w", + "qwertysyms_o", + "keylabel_to_more_symbol", + "qwertysyms_k", + "qwertysyms_s", + "actions_n", + "number_4", + "morekeys_misc_x", + "number_2", "morekeys_tablet_double_quote", + "morekeys_misc_b", + "actions_0", + "qwertysyms_u", + "actions_v", + "morekeys_symbols_1", + "keyspec_emoji_action_key_navigation", + "qwertysyms_5", + "qwertysyms_n", + "qwertysyms_m", + "qwertysyms_h", + "actions_7", + "single_laqm_raqm", + "qwertysyms_2", + "double_lqm_rqm", + "number_9", + "qwertysyms_b", + "actions_g", + "number_0", + "morekeys_symbols_0", + "actions_q", + "qwertysyms_y", + "qwertysyms_l", + "actions_8", + "keylabel_time_am", + "single_rqm_9qm", + "qwertysyms_j", "keylabel_time_pm", - "actions_1" + "actions_o", + "morekeys_v", + "qwertysyms_d", + "single_lqm_rqm", + "morekeys_misc_j", + "keylabel_to_phone_numeric", + "morekeys_misc_p", + "actions_6", + "actions_k", + "qwertysyms_c", + "actions_b", + "double_raqm_laqm", + "morekeys_f", + "keylabel_tablet_to_more_symbol", + "qwertysyms_r", + "keyspecs_right_parenthesis_more_keys", + "qwertysyms_f", + "keyspec_shortcut", + "qwertysyms_3", + "actions_r", + "qwertysyms_7", + "actions_5", + "keyspec_emoji_action_key", + "qwertysyms_w", + "number_7", + "morekeys_symbols_5", + "actions_z", + "morekeys_b", + "morekeys_misc_k", + "qwertysyms_v", + "morekeys_symbols_3", + "single_raqm_laqm", + "morekeys_symbols_9", + "qwertysyms_q", + "actions_x", + "actions_1", + "number_6", + "morekeys_currency_generic", + "morekeys_symbols_4", + "keyspec_settings", + "actions_c", + "double_laqm_raqm", + "number_3", + "qwertysyms_6", + "morekeys_double_quote", + "qwertysyms_i", + "qwertysyms_z", + "morekeys_symbols_2", + "qwertysyms_0", + "qwertysyms_9", + "actions_i", + "actions_3", + "morekeys_single_quote", + "qwertysyms_g", + "keyspecs_left_parenthesis_more_keys", + "qwertysyms_p", + "actions_f", + "keyspec_popular_domain", + "qwertysyms_x", + "double_rqm_9qm", + "morekeys_p", + "morekeys_am_pm", + "actions_m", + "keyspec_action_previous", + "qwertysyms_t", + "actions_p", + "actions_d", + "actions_4", + "double_9qm_rqm", + "actions_s", + "morekeys_symbols_6", + "morekeys_symbols_7", + "double_9qm_lqm", + "number_8", + "single_9qm_rqm", + "qwertysyms_a", + "number_5", + "morekeys_misc_f", + "actions_e", + "morekeys_q", + "morekeys_symbols_8", + "morekeys_misc_v", + "actions_y", + "actions_j", + "keylabel_to_phone_symbols" }; private static final String EMPTY = ""; @@ -374,8 +374,8 @@ public final class KeyboardTextsTable { private static final String[] TEXTS_af = { "af", null, - "\u00e1", "\u00f3,\u00f4", + "\u00e1", "\u00fa,\u00fb", "\u00e9,\u00e8,\u00ea,\u00eb", "\u00ed,\u00ec,\u00ef,\u00ee", @@ -384,10 +384,12 @@ public final class KeyboardTextsTable { null, null, null, - "\u00f6,\u00f2,\u00f5,\u0153,\u00f8,\u014d", "\u00e2,\u00e4,\u00e0,\u00e6,\u00e3,\u00e5,\u0101", + "\u00f6,\u00f2,\u00f5,\u0153,\u00f8,\u014d", "\u00fc,\u00f9,\u016b", "\u0119,\u0117,\u0113", + null, + null, "\u012f,\u012b,\u0133" }; @@ -416,33 +418,36 @@ public final class KeyboardTextsTable { null, null, null, - "8", + "\u0669", + "\u0668", + "9", + "5", + "\u0665", + "\u0663", + "\u0666", + "\u0661", + null, + "0,\u066b,\u066c", + "\u0664", + "7", "6", null, - "\u0669", - null, - "9", - "\u0665", - "\u0664", - "3", - null, - "1", - "\u0667", - "\u0668", - "\u0666", - "\u0663", - "4", - "5", - "0,\u066b,\u066c", "2", - "7", - "\u0661", + null, + "8", + "3", "\u0662", + "\u0667", "\u0660", + "4", + "1", + null, "\u0663\u0662\u0661\u061f", + "!text/morekeys_arabic_diacritics", + null, null, "!text/morekeys_arabic_diacritics", - "!text/morekeys_arabic_diacritics", + null, null, null, "\u060c", @@ -453,56 +458,56 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, - null, "<|>", "!fixedColumnOrder!4,:,!,\u061f,\u061b,-,\\\",\\'", + "\u2264|\u2265", + ")|(", + "(|)", + "\u00bb|\u00ab", + "]|[", + "\u0651", + null, + "[|]", + null, + "\u060c", + null, + "\u2265|\u2264", + "\u2605,\u066d", + "}|{", "\u2039|\u203a", null, - "{|}", - null, - "]|[", - ")|(", - "\u00ab|\u00bb", - "\u2264|\u2265", - "[|]", - ">|<", - "}|{", - "\u060c", - "(|)", - "\u2605,\u066d", - null, - null, - "\u0651", "?,\u00bf", - "\u00bb|\u00ab", - "\u2265|\u2264", + "{|}", + "\u00ab|\u00bb", null, + ">|<", "\u203a|\u2039", - "\u066a", + null, null, "\u266a", null, - null, - "!fixedColumnOrder!8, \u0654\u25cc|\u0654, \u0652\u25cc|\u0652, \u064d\u25cc|\u064d, \u064c\u25cc|\u064c, \u0651\u25cc|\u0651, \u064b\u25cc|\u064b,!text/keyspec_symbols_question,!, \u0656\u25cc|\u0656, \u0670\u25cc|\u0670, \u0653\u25cc|\u0653, \u0650\u25cc|\u0650, \u064f\u25cc|\u064f,\u0640, \u0655\u25cc|\u0655, \u064e\u25cc|\u064e", - "\u061f", - null, - null, ";", + null, + "\u0651", + null, + "\u061f", "!fixedColumnOrder!4,\ufd3f|\ufd3e,!text/keyspecs_right_parenthesis_more_keys", "\\%,\u2030", "!fixedColumnOrder!4,\ufd3e|\ufd3f,!text/keyspecs_left_parenthesis_more_keys", - "\u061f", + null, "\u061b", - "\u0651" + "\u066a", + "\u061f", + null, + null, + "!fixedColumnOrder!8, \u0654\u25cc|\u0654, \u0652\u25cc|\u0652, \u064d\u25cc|\u064d, \u064c\u25cc|\u064c, \u0651\u25cc|\u0651, \u064b\u25cc|\u064b,!text/keyspec_symbols_question,!, \u0656\u25cc|\u0656, \u0670\u25cc|\u0670, \u0653\u25cc|\u0653, \u0650\u25cc|\u0650, \u064f\u25cc|\u064f,\u0640, \u0655\u25cc|\u0655, \u064e\u25cc|\u064e" }; private static final String[] TEXTS_az = { "az", null, - "\u00e2,\u00e4,\u00e1", "\u00f6,\u00f4,\u0153,\u00f2,\u00f3,\u00f5,\u00f8,\u014d", + "\u00e2,\u00e4,\u00e1", "\u00fc,\u00fb,\u00f9,\u00fa,\u016b", "\u0259,\u00e9", "\u0131,\u00ee,\u00ef,\u00ec,\u00ed,\u012f,\u012b", @@ -515,15 +520,14 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u017e", "\u0148,\u00f1", null, null, null, null, - "\u00fd", null, + "\u00fd", null, null, null, @@ -583,19 +587,21 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u0451", null, null, + "\u044b", + null, + null, null, - "\u0456", null, "\u045e", null, + "\u0456", + null, + null, null, - "\u044b", "\u044a", - null, "\u044d" }; @@ -635,29 +641,29 @@ public final class KeyboardTextsTable { null, null, null, - "8", + "\u09ef", + "\u09ee", + "9", + "5", + "\u09eb", + "\u09e9", + "\u09ec", + "\u09e7", + null, + "0", + "\u09ea", + "7", "6", null, - "\u09ef", - null, - "9", - "\u09eb", - "\u09ea", - "3", - null, - "1", - "\u09ed", - "\u09ee", - "\u09ec", - "\u09e9", - "4", - "5", - "0", "2", - "7", - "\u09e7", + null, + "8", + "3", "\u09e8", - "\u09e6" + "\u09ed", + "\u09e6", + "4", + "1" }; private static final String[] TEXTS_bn_IN = { @@ -677,8 +683,8 @@ public final class KeyboardTextsTable { private static final String[] TEXTS_ca = { "ca", null, - "\u00e0", "\u00f2,\u00f3", + "\u00e0", "\u00fa,\u00fc", "\u00e8,\u00e9", "\u00ed,\u00ef", @@ -687,14 +693,13 @@ public final class KeyboardTextsTable { "\u00e7", null, null, - "\u00f6,\u00f4,\u00f5,\u00f8,\u0153,\u014d,\u00ba", "\u00e1,\u00e4,\u00e2,\u00e3,\u00e5,\u0105,\u00e6,\u0101,\u00aa", + "\u00f6,\u00f4,\u00f5,\u00f8,\u0153,\u014d,\u00ba", "\u00f9,\u00fb,\u016b", "\u00eb,\u00ea,\u0119,\u0117,\u0113", + null, + null, "\u00ec,\u00ee,\u012f,\u012b", - null, - null, - null, "\u0107,\u010d", null, null, @@ -750,11 +755,6 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, - null, - null, - null, "!autoColumnOrder!9,\\\\,?,!,\u00b7,#,),(,/,;,',@,:,-,\\\",+,\\%,&", null, null, @@ -770,6 +770,17 @@ public final class KeyboardTextsTable { null, null, null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, "\u00e7", null, null, @@ -790,8 +801,6 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, "!autoColumnOrder!8,\\\\,',\u00b7,#,),(,/,;,@,:,-,\\\",+,\\%,&" }; @@ -820,93 +829,96 @@ public final class KeyboardTextsTable { null, null, null, - "8", + "\u0669", + "\u0668", + "9", + "5", + "\u0665", + "\u0663", + "\u0666", + "\u0661", + null, + "0,\u066b,\u066c", + "\u0664", + "7", "6", null, - "\u0669", - null, - "9", - "\u0665", - "\u0664", - "3", - null, - "1", - "\u0667", - "\u0668", - "\u0666", - "\u0663", - "4", - "5", - "0,\u066b,\u066c", "2", - "7", - "\u0661", + null, + "8", + "3", "\u0662", + "\u0667", "\u0660", + "4", + "1", + null, "\u0663\u0662\u0661\u061f", + "\u061f", + null, null, "\u061f", - "\u061f", + null, null, null, "\u060c", null, - null, - null, - null, - null, - null, - null, ".", null, null, + null, + null, + null, "<|>", "!fixedColumnOrder!4,:,!,\u061f,\u061b,-,\\\",\\'", + "\u2264|\u2265", + ")|(", + "(|)", + "\u00bb|\u00ab", + "]|[", + "\u0651", + null, + "[|]", + null, + "\u060c", + null, + "\u2265|\u2264", + "\u2605,\u066d", + "}|{", "\u2039|\u203a", null, - "{|}", - null, - "]|[", - ")|(", - "\u00ab|\u00bb", - "\u2264|\u2265", - "[|]", - ">|<", - "}|{", - "\u060c", - "(|)", - "\u2605,\u066d", - null, - null, - "\u0651", "?,\u00bf", - "\u00bb|\u00ab", - "\u2265|\u2264", + "{|}", + "\u00ab|\u00bb", null, + ">|<", "\u203a|\u2039", - "\u066a", + null, null, "\u266a", null, - null, - "!fixedColumnOrder!7, \u0655\u25cc|\u0655, \u0654\u25cc|\u0654, \u0652\u25cc|\u0652, \u064d\u25cc|\u064d, \u064c\u25cc|\u064c, \u064b\u25cc|\u064b, \u0651\u25cc|\u0651, \u0656\u25cc|\u0656, \u0670\u25cc|\u0670, \u0653\u25cc|\u0653, \u0650\u25cc|\u0650, \u064f\u25cc|\u064f, \u064e\u25cc|\u064e,\u0640|\u0640", - "\u061f", - null, - null, ";", + null, + "\u0651", + null, + "\u061f", "!fixedColumnOrder!4,\ufd3f|\ufd3e,!text/keyspecs_right_parenthesis_more_keys", "\\%,\u2030", "!fixedColumnOrder!4,\ufd3e|\ufd3f,!text/keyspecs_left_parenthesis_more_keys", - "\u061f", + null, "\u061b", - "\u0651" + "\u066a", + "\u061f", + null, + null, + "!fixedColumnOrder!7, \u0655\u25cc|\u0655, \u0654\u25cc|\u0654, \u0652\u25cc|\u0652, \u064d\u25cc|\u064d, \u064c\u25cc|\u064c, \u064b\u25cc|\u064b, \u0651\u25cc|\u0651, \u0656\u25cc|\u0656, \u0670\u25cc|\u0670, \u0653\u25cc|\u0653, \u0650\u25cc|\u0650, \u064f\u25cc|\u064f, \u064e\u25cc|\u064e,\u0640|\u0640" }; private static final String[] TEXTS_cs = { "cs", null, - "\u00e1", "\u00f3", + "\u00e1", "\u00fa,\u016f", "\u00e9,\u011b", "\u00ed", @@ -915,36 +927,34 @@ public final class KeyboardTextsTable { "\u010d", null, "\u0161", - "\u00f6,\u00f4,\u00f2,\u00f5,\u0153,\u00f8,\u014d", "\u00e0,\u00e2,\u00e4,\u00e6,\u00e3,\u00e5,\u0101", + "\u00f6,\u00f4,\u00f2,\u00f5,\u0153,\u00f8,\u014d", "\u00fb,\u00fc,\u00f9,\u016b", "\u00e8,\u00ea,\u00eb,\u0119,\u0117,\u0113", - "\u00ee,\u00ef,\u00ec,\u012f,\u012b", "\u017e", "\u0148", - "\u00df,\u015b", + "\u00ee,\u00ef,\u00ec,\u012f,\u012b", "\u00e7,\u0107", + "\u00df,\u015b", "!text/double_raqm_laqm", "!text/single_raqm_laqm", "\u00fd", null, null, - "\u010f", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, null, "\u017a,\u017c", null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, + "\u010f", null, null, null, @@ -965,13 +975,18 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u0165", null, null, null, null, null, + null, + null, + null, + null, + null, + null, "\u0159", null, null, @@ -988,34 +1003,14 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, "\u00ff" }; private static final String[] TEXTS_da = { "da", null, - "\u00e5,\u00e6", "\u00f8", + "\u00e5,\u00e6", null, null, null, @@ -1024,8 +1019,8 @@ public final class KeyboardTextsTable { null, null, null, - "\u00f6,\u00f3,\u00f4,\u00f2,\u00f5,\u0153,\u014d", "\u00e1,\u00e4,\u00e0,\u00e2,\u00e3,\u0101", + "\u00f6,\u00f3,\u00f4,\u00f2,\u00f5,\u0153,\u014d", null, null, null, @@ -1063,15 +1058,16 @@ public final class KeyboardTextsTable { null, null, null, - "\u00e4", - null, - null, + "\u00f8", null, null, "\u00e6", null, null, - "\u00f8", + null, + null, + "\u00e4", + null, null, null, "\u00e5", @@ -1093,14 +1089,17 @@ public final class KeyboardTextsTable { null, null, null, + null, + null, + null, "\u00f6" }; private static final String[] TEXTS_de = { "de", null, - "\u00e4", "\u00f6", + "\u00e4", "\u00fc", null, null, @@ -1109,15 +1108,15 @@ public final class KeyboardTextsTable { null, null, "\u00df", - "%,\u00f4,\u00f2,\u00f3,\u00f5,\u0153,\u00f8,\u014d", "%,\u00e2,\u00e0,\u00e1,\u00e6,\u00e3,\u00e5,\u0101", + "%,\u00f4,\u00f2,\u00f3,\u00f5,\u0153,\u00f8,\u014d", "%,\u00fb,\u00f9,\u00fa,\u016b", null, null, null, null, - "\u015b,\u0161", null, + "\u015b,\u0161", "!text/double_raqm_laqm", "!text/single_raqm_laqm", null, @@ -1186,24 +1185,23 @@ public final class KeyboardTextsTable { null, null, null, + "\u00fc", + null, + "\u00e8", + null, "\u00e4", null, "\u00f6", - "\u00e8", null, null, null, - "\u00e9", - null, - null, null, null, null, null, null, "\u00e0", - null, - "\u00fc" + "\u00e9" }; private static final String[] TEXTS_el = { @@ -1235,9 +1233,8 @@ public final class KeyboardTextsTable { null, null, null, - "\u00df,\u0161,\u015b,\u0219,\u015f", "\u0107,\u010d,\u00e7,\u010b", - null, + "\u00df,\u0161,\u015b,\u0219,\u015f", null, null, null, @@ -1311,6 +1308,12 @@ public final class KeyboardTextsTable { null, null, null, + null, + null, + null, + null, + null, + null, "\u0135", null, null, @@ -1320,13 +1323,6 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, - null, - null, - null, - null, - null, "\u011f,\u0121,\u0123", null, null, @@ -1341,32 +1337,32 @@ public final class KeyboardTextsTable { null, null, null, + null, + null, + null, + null, + null, + null, "\u0125", null, - null, - null, + "\u016d", + "\u0127", null, null, null, "\u015d", - "\u016d", - null, - null, - null, "\u0109", null, null, null, - "\u011d", - null, - "\u0127" + "\u011d" }; private static final String[] TEXTS_es = { "es", null, - "\u00e1", "\u00f3", + "\u00e1", "\u00fa,\u00fc", "\u00e9", "\u00ed", @@ -1375,15 +1371,13 @@ public final class KeyboardTextsTable { null, null, null, - "\u00f2,\u00f6,\u00f4,\u00f5,\u00f8,\u0153,\u014d,\u00ba", "\u00e0,\u00e4,\u00e2,\u00e3,\u00e5,\u0105,\u00e6,\u0101,\u00aa", + "\u00f2,\u00f6,\u00f4,\u00f5,\u00f8,\u0153,\u014d,\u00ba", "\u00f9,\u00fb,\u016b", "\u00e8,\u00eb,\u00ea,\u0119,\u0117,\u0113", - "\u00ef,\u00ec,\u00ee,\u012f,\u012b", null, "\u00f1", - null, - null, + "\u00ef,\u00ec,\u00ee,\u012f,\u012b", null, null, null, @@ -1439,18 +1433,14 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, - null, - null, "!autoColumnOrder!9,\\\\,?,!,#,),(,/,;,\u00a1,',@,:,-,\\\",+,\\%,&,\u00bf" }; private static final String[] TEXTS_et = { "et", null, - "\u00e4", "\u00f6,\u00f5", + "\u00e4", "\u00fc", null, null, @@ -1459,13 +1449,14 @@ public final class KeyboardTextsTable { null, null, "\u0161", - "\u00f2,\u00f3,\u00f4,\u0153,\u0151,\u00f8", "\u0101,\u00e0,\u00e1,\u00e2,\u00e3,\u00e5,\u00e6,\u0105", + "\u00f2,\u00f3,\u00f4,\u0153,\u0151,\u00f8", "\u016b,\u0173,\u00f9,\u00fa,\u00fb,\u016f,\u0171", null, - null, "\u017e", null, + null, + null, "\u00df,\u015b,\u015f", null, null, @@ -1475,6 +1466,14 @@ public final class KeyboardTextsTable { null, null, null, + null, + null, + null, + null, + null, + null, + null, + null, "\u017c,\u017a", null, null, @@ -1489,11 +1488,10 @@ public final class KeyboardTextsTable { null, null, null, + "\u00e4", null, null, - null, - null, - null, + "\u00f6", null, null, null, @@ -1502,21 +1500,14 @@ public final class KeyboardTextsTable { null, null, null, - null, - "\u00f6", - null, - null, - "\u00e4", - null, - null, "\u00fc" }; private static final String[] TEXTS_eu = { "eu", null, - "\u00e1,\u00e0,\u00e4,\u00e2,\u00e3,\u00e5,\u0105,\u00e6,\u0101,\u00aa", "\u00f3,\u00f2,\u00f6,\u00f4,\u00f5,\u00f8,\u0153,\u014d,\u00ba", + "\u00e1,\u00e0,\u00e4,\u00e2,\u00e3,\u00e5,\u0105,\u00e6,\u0101,\u00aa", "\u00fa,\u00fc,\u00f9,\u00fb,\u016b", "\u00e9,\u00e8,\u00eb,\u00ea,\u0119,\u0117,\u0113", "\u00ed,\u00ef,\u00ec,\u00ee,\u012f,\u012b", @@ -1530,7 +1521,6 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u00f1,\u0144" }; @@ -1559,33 +1549,36 @@ public final class KeyboardTextsTable { null, null, null, - "8", + "\u06f9", + "\u06f8", + "9", + "5", + "\u06f5", + "\u06f3", + "\u06f6", + "\u06f1", + null, + "0,\u066b,\u066c", + "\u06f4", + "7", "6", null, - "\u06f9", - null, - "9", - "\u06f5", - "\u06f4", - "3", - null, - "1", - "\u06f7", - "\u06f8", - "\u06f6", - "\u06f3", - "4", - "5", - "0,\u066b,\u066c", "2", - "7", - "\u06f1", + null, + "8", + "3", "\u06f2", + "\u06f7", "\u06f0", + "4", + "1", + null, "\u06f3\u06f2\u06f1\u061f", + "!text/morekeys_arabic_diacritics", + null, null, "!text/morekeys_arabic_diacritics", - "!text/morekeys_arabic_diacritics", + null, null, null, "\u060c", @@ -1596,49 +1589,53 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, - null, "<|>", "!fixedColumnOrder!4,:,!,\u061f,\u061b,-,!text/keyspec_left_double_angle_quote,!text/keyspec_right_double_angle_quote", + "\u2264|\u2265", + ")|(", + "(|)", + "\u00bb|\u00ab", + "]|[", + "\u064b", + null, + "[|]", + null, + "\u060c", + null, + "\u2265|\u2264", + "\u2605,\u066d", + "}|{", "\u2039|\u203a", null, - "{|}", - null, - "]|[", - ")|(", - "\u00ab|\u00bb", - "\u2264|\u2265", - "[|]", - ">|<", - "}|{", - "\u060c", - "(|)", - "\u2605,\u066d", - null, - null, - "\u064b", "?,\u00bf", - "\u00bb|\u00ab", - "\u2265|\u2264", + "{|}", + "\u00ab|\u00bb", null, + ">|<", "\u203a|\u2039", - "\u066a", + null, null, "\u266a", null, - null, - "!fixedColumnOrder!8, \u0654\u25cc|\u0654, \u0652\u25cc|\u0652, \u064d\u25cc|\u064d, \u064c\u25cc|\u064c, \u0651\u25cc|\u0651, \u064b\u25cc|\u064b,!text/keyspec_symbols_question,!, \u0656\u25cc|\u0656, \u0670\u25cc|\u0670, \u0653\u25cc|\u0653, \u0650\u25cc|\u0650, \u064f\u25cc|\u064f,\u0640, \u0655\u25cc|\u0655, \u064e\u25cc|\u064e", - "\u061f", - null, - null, ";", + null, + "\u064b", + null, + "\u061f", "!fixedColumnOrder!4,\ufd3f|\ufd3e,!text/keyspecs_right_parenthesis_more_keys", "\\%,\u2030", "!fixedColumnOrder!4,\ufd3e|\ufd3f,!text/keyspecs_left_parenthesis_more_keys", - "\u061f", + null, "\u061b", - "\u064b", + "\u066a", + "\u061f", + null, + null, + "!fixedColumnOrder!8, \u0654\u25cc|\u0654, \u0652\u25cc|\u0652, \u064d\u25cc|\u064d, \u064c\u25cc|\u064c, \u0651\u25cc|\u0651, \u064b\u25cc|\u064b,!text/keyspec_symbols_question,!, \u0656\u25cc|\u0656, \u0670\u25cc|\u0670, \u0653\u25cc|\u0653, \u0650\u25cc|\u0650, \u064f\u25cc|\u064f,\u0640, \u0655\u25cc|\u0655, \u064e\u25cc|\u064e", + null, + null, + null, + null, null, null, null, @@ -1671,23 +1668,14 @@ public final class KeyboardTextsTable { null, null, "!fixedColumnOrder!3,!text/keyspec_left_single_angle_quote,!text/keyspec_less_than_equal,!text/keyspec_less_than", - null, - null, - null, - null, - null, - null, - null, - null, - null, "!fixedColumnOrder!3,!text/keyspec_right_single_angle_quote,!text/keyspec_greater_than_equal,!text/keyspec_greater_than" }; private static final String[] TEXTS_fi = { "fi", null, - "\u00e4,\u00e5", "\u00f6", + "\u00e4,\u00e5", null, null, null, @@ -1696,13 +1684,14 @@ public final class KeyboardTextsTable { null, null, "\u0161", - "\u00f8,\u00f4,\u00f2,\u00f3,\u00f5,\u0153,\u014d", "\u00e6,\u00e0,\u00e1,\u00e2,\u00e3,\u0101", - null, + "\u00f8,\u00f4,\u00f2,\u00f3,\u00f5,\u0153,\u014d", null, null, "\u017e", null, + null, + null, "\u00df,\u015b", null, null, @@ -1712,6 +1701,14 @@ public final class KeyboardTextsTable { null, null, null, + null, + null, + null, + null, + null, + null, + null, + null, "\u017a,\u017c", null, null, @@ -1726,11 +1723,10 @@ public final class KeyboardTextsTable { null, null, null, + "\u00e4", null, null, - null, - null, - null, + "\u00f6", null, null, null, @@ -1739,13 +1735,6 @@ public final class KeyboardTextsTable { null, null, null, - null, - "\u00f6", - null, - null, - "\u00e4", - null, - null, "\u00e5", null, null, @@ -1765,14 +1754,17 @@ public final class KeyboardTextsTable { null, null, null, + null, + null, + null, "\u00e6" }; private static final String[] TEXTS_fr = { "fr", null, - "\u00e0,\u00e2,%,\u00e6", "\u00f4,\u0153", + "\u00e0,\u00e2,%,\u00e6", "\u00f9,\u00fb,%,\u00fc", "\u00e9,\u00e8,\u00ea,\u00eb", "\u00ee,%,\u00ef", @@ -1781,17 +1773,17 @@ public final class KeyboardTextsTable { "\u00e7", null, null, - "%,\u00f6,\u00f2,\u00f3,\u00f5,\u00f8,\u014d,\u00ba", "\u00e1,\u00e4,\u00e3,\u00e5,\u0101,\u00aa", + "%,\u00f6,\u00f2,\u00f3,\u00f5,\u00f8,\u014d,\u00ba", "\u00fa,\u016b", "%,\u0119,\u0117,\u0113", + null, + null, "\u00ec,\u00ed,\u012f,\u012b", - null, - null, - null, "%,\u0107,\u010d", null, null, + null, "%,\u00ff", null, null, @@ -1858,31 +1850,30 @@ public final class KeyboardTextsTable { null, null, null, + "\u00e8", + null, + "\u00fc", + null, "\u00e0", null, "\u00e9", - "\u00fc", null, null, null, - "\u00f6", - null, - null, null, null, null, null, null, "\u00e4", - null, - "\u00e8" + "\u00f6" }; private static final String[] TEXTS_gl = { "gl", null, - "\u00e1,\u00e0,\u00e4,\u00e2,\u00e3,\u00e5,\u0105,\u00e6,\u0101,\u00aa", "\u00f3,\u00f2,\u00f6,\u00f4,\u00f5,\u00f8,\u0153,\u014d,\u00ba", + "\u00e1,\u00e0,\u00e4,\u00e2,\u00e3,\u00e5,\u0105,\u00e6,\u0101,\u00aa", "\u00fa,\u00fc,\u00f9,\u00fb,\u016b", "\u00e9,\u00e8,\u00eb,\u00ea,\u0119,\u0117,\u0113", "\u00ed,\u00ef,\u00ec,\u00ee,\u012f,\u012b", @@ -1896,7 +1887,6 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u00f1,\u0144" }; @@ -1925,43 +1915,40 @@ public final class KeyboardTextsTable { null, null, null, - "8", + "\u096f", + "\u096e", + "9", + "5", + "\u096b", + "\u0969", + "\u096c", + "\u0967", + null, + "0", + "\u096a", + "7", "6", null, - "\u096f", - null, - "9", - "\u096b", - "\u096a", - "3", - null, - "1", - "\u096d", - "\u096e", - "\u096c", - "\u0969", - "4", - "5", - "0", "2", - "7", - "\u0967", - "\u0968", - "\u0966", - "?\u0967\u0968\u0969", null, + "8", + "3", + "\u0968", + "\u096d", + "\u0966", + "4", + "1", + null, + "?\u0967\u0968\u0969", "!autoColumnOrder!8,\\\\,.,',#,),(,/,;,@,:,-,\\\",+,\\%,&", + null, + null, "!autoColumnOrder!9,\\\\,.,?,!,#,),(,/,;,',@,:,-,\\\",+,\\%,&", null, null, null, null, null, - null, - null, - null, - null, - null, "\u0964", null, null, @@ -1985,8 +1972,6 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, "\u0964" }; @@ -2099,29 +2084,23 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, - "Send", - null, - null, - null, - null, - null, - null, - null, - null, + "Wait", null, "Prev", + "Search", + null, + null, + "Done", + null, + "Go", + null, null, - "Next", - "Wait", "Pause", null, null, null, - "Go", - "Done", - "Search" + "Next", + "Send" }; private static final String[] TEXTS_hr = { @@ -2141,26 +2120,37 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u017e", null, - "\u015b,\u00df", + null, "\u00e7", + "\u015b,\u00df", "!text/double_raqm_laqm", "!text/single_raqm_laqm", null, null, null, - "\u0111", null, - "\u017a,\u017c" + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + "\u017a,\u017c", + null, + "\u0111" }; private static final String[] TEXTS_hu = { "hu", null, - "\u00e1", "\u00f3,\u00f6,\u0151", + "\u00e1", "\u00fa,\u00fc,\u0171", "\u00e9", "\u00ed", @@ -2169,15 +2159,15 @@ public final class KeyboardTextsTable { null, null, null, - "\u00f4,\u00f2,\u00f5,\u0153,\u00f8,\u014d", "\u00e0,\u00e2,\u00e4,\u00e6,\u00e3,\u00e5,\u0101", + "\u00f4,\u00f2,\u00f5,\u0153,\u00f8,\u014d", "\u00fb,\u00f9,\u016b", "\u00e8,\u00ea,\u00eb,\u0119,\u0117,\u0113", + null, + null, "\u00ee,\u00ef,\u00ec,\u012f,\u012b", null, null, - null, - null, "!text/double_raqm_laqm", "!text/single_raqm_laqm" }; @@ -2236,14 +2226,11 @@ public final class KeyboardTextsTable { null, null, null, + null, + null, + null, "\u055d", null, - null, - null, - null, - null, - null, - null, "\u0589", null, null, @@ -2260,16 +2247,22 @@ public final class KeyboardTextsTable { null, null, null, - "\u055d", - null, - null, "!autoColumnOrder!8,\\,,\u055e,\u055c,.,\u055a,\u0559,?,!,\u055d,\u055b,\u058a,\u00bb,\u00ab,\u055f,;,:", + "\u055d", + null, null, null, - "\u055e,\u00bf", null, null, "\u0589", + "\u055e,\u00bf", + null, + null, + null, + null, + null, + null, + null, null, null, null, @@ -2325,8 +2318,8 @@ public final class KeyboardTextsTable { private static final String[] TEXTS_is = { "is", null, - "\u00e1,\u00e4,\u00e6", "\u00f3,\u00f6", + "\u00e1,\u00e4,\u00e6", "\u00fa", "\u00e9", "\u00ed", @@ -2335,20 +2328,33 @@ public final class KeyboardTextsTable { null, null, null, - "\u00f4,\u00f2,\u00f5,\u0153,\u00f8,\u014d", "\u00e5,\u00e0,\u00e2,\u00e3,\u0101", + "\u00f4,\u00f2,\u00f5,\u0153,\u00f8,\u014d", "\u00fc,\u00fb,\u00f9,\u016b", "\u00eb,\u00e8,\u00ea,\u0119,\u0117,\u0113", + null, + null, "\u00ef,\u00ee,\u00ec,\u012f,\u012b", null, null, null, null, - null, - null, "\u00fd", null, null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, "\u00f0", null, null, @@ -2370,22 +2376,6 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, "\u00fe", null, null, @@ -2414,28 +2404,14 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, "\u00ff" }; private static final String[] TEXTS_it = { "it", null, - "\u00e0", "\u00f2", + "\u00e0", "\u00f9", "\u00e8,\u00e9", "\u00ec", @@ -2444,10 +2420,12 @@ public final class KeyboardTextsTable { null, null, null, - "\u00f3,\u00f4,\u00f6,\u00f5,\u0153,\u00f8,\u014d,\u00ba", "\u00e1,\u00e2,\u00e4,\u00e6,\u00e3,\u00e5,\u0101,\u00aa", + "\u00f3,\u00f4,\u00f6,\u00f5,\u0153,\u00f8,\u014d,\u00ba", "\u00fa,\u00fb,\u00fc,\u016b", "\u00ea,\u00eb,\u0119,\u0117,\u0113", + null, + null, "\u00ed,\u00ee,\u00ef,\u012f,\u012b", null, null, @@ -2519,26 +2497,23 @@ public final class KeyboardTextsTable { null, null, null, + "\u00fc", null, + "\u00e8", null, "\u00e4", null, "\u00f6", - "\u00e8", null, null, null, - "\u00e9", - null, - null, null, null, null, null, null, "\u00e0", - null, - "\u00fc" + "\u00e9" }; private static final String[] TEXTS_iw = { @@ -2608,27 +2583,27 @@ public final class KeyboardTextsTable { null, "<|>", null, + "\u2264|\u2265", + ")|(", + "(|)", + "\u00bb|\u00ab", + "]|[", + null, + null, + "[|]", + null, + null, + null, + "\u2265|\u2264", + "\u2605", + "}|{", "\u2039|\u203a", null, + null, "{|}", - null, - "]|[", - ")|(", "\u00ab|\u00bb", - "\u2264|\u2265", - "[|]", + null, ">|<", - "}|{", - null, - "(|)", - "\u2605", - null, - null, - null, - null, - "\u00bb|\u00ab", - "\u2265|\u2264", - null, "\u203a|\u2039", null, null, @@ -2682,12 +2657,6 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, - null, - null, - null, - null, "\u00b1,\ufb29" }; @@ -2751,19 +2720,21 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u0451", null, null, + "\u044b", + null, + null, null, - "\u0438", null, "\u0449", null, + "\u0438", + null, + null, null, - "\u044b", "\u044a", - null, "\u044d", null, null, @@ -2809,6 +2780,7 @@ public final class KeyboardTextsTable { null, null, null, + "\u04a3", null, null, null, @@ -2816,39 +2788,38 @@ public final class KeyboardTextsTable { null, null, null, + null, + null, + null, + "\u0493", + null, + null, + null, + null, + null, + null, "\u04af,\u04b1", - null, - null, - "\u04a3", - null, - null, - "\u0493", "\u04e9", null, null, null, - null, - null, - null, "\u0456", null, null, null, - null, - null, - null, - null, - null, - null, - null, - null, "\u04d9", + "\u04bb", null, null, null, - "\u049b", null, - "\u04bb" + null, + null, + null, + null, + null, + null, + "\u049b" }; private static final String[] TEXTS_km = { @@ -2986,6 +2957,16 @@ public final class KeyboardTextsTable { null, null, null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, "\u17db,\u00a2,\u00a3,\u20ac,\u00a5,\u20b1" }; @@ -3051,19 +3032,21 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u0451", null, null, + "\u044b", + null, + null, null, - "\u0438", null, "\u0449", null, + "\u0438", + null, + null, null, - "\u044b", "\u044a", - null, "\u044d", null, null, @@ -3109,6 +3092,17 @@ public final class KeyboardTextsTable { null, null, null, + "\u04a3", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, null, null, null, @@ -3117,12 +3111,6 @@ public final class KeyboardTextsTable { null, null, "\u04af", - null, - null, - "\u04a3", - null, - null, - null, "\u04e9" }; @@ -3143,8 +3131,8 @@ public final class KeyboardTextsTable { private static final String[] TEXTS_lt = { "lt", null, - "\u0105", null, + "\u0105", "\u016b,\u0173", "\u0117,\u0119", "\u012f", @@ -3157,15 +3145,14 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u017e" }; private static final String[] TEXTS_lv = { "lv", null, - "\u0101", "\u014d", + "\u0101", "\u016b", "\u0113", "\u012b", @@ -3174,15 +3161,15 @@ public final class KeyboardTextsTable { "\u010d", null, "\u0161", - "\u00f2,\u00f3,\u00f4,\u00f5,\u00f6,\u0153,\u0151,\u00f8", "\u00e0,\u00e1,\u00e2,\u00e3,\u00e4,\u00e5,\u00e6,\u0105", + "\u00f2,\u00f3,\u00f4,\u00f5,\u00f6,\u0153,\u0151,\u00f8", "\u0173,\u00f9,\u00fa,\u00fb,\u00fc,\u016f,\u0171", "\u0117,\u00e8,\u00e9,\u00ea,\u00eb,\u0119,\u011b", - "\u012f,\u00ec,\u00ed,\u00ee,\u00ef,\u0131", "\u017e", "\u0146", - "\u00df,\u015b,\u015f", + "\u012f,\u00ec,\u00ed,\u00ee,\u00ef,\u0131", "\u00e7,\u0107", + "\u00df,\u015b,\u015f", null, null, null, @@ -3190,7 +3177,6 @@ public final class KeyboardTextsTable { null, null, null, - "\u017c,\u017a", null, null, null, @@ -3200,8 +3186,7 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, + "\u017c,\u017a", null, null, null, @@ -3229,12 +3214,18 @@ public final class KeyboardTextsTable { null, null, null, - "\u013c", + null, + null, + null, + null, + null, + null, null, "\u0157", null, null, null, + "\u013c", null, null, null, @@ -3267,16 +3258,19 @@ public final class KeyboardTextsTable { null, null, null, + "\u011f", + null, + null, + null, + "\u0142,\u013a,\u013e", null, null, null, "\u0159,\u0155", null, null, - "\u011f", null, - "\u0137", - "\u0142,\u013a,\u013e" + "\u0137" }; private static final String[] TEXTS_mk = { @@ -3327,7 +3321,6 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u0450", null, null, @@ -3387,27 +3380,29 @@ public final class KeyboardTextsTable { null, null, null, - "\u0453", + null, + null, + null, + null, + null, null, "\u045c", null, null, + "\u0437", + null, + null, + null, + null, + null, + null, + "\u0453", null, null, null, null, "\u045d", - null, - null, - null, - null, - "\u0455", - null, - null, - null, - null, - null, - "\u0437" + "\u0455" }; private static final String[] TEXTS_ml = { @@ -3463,29 +3458,30 @@ public final class KeyboardTextsTable { null, null, null, - "8", + "\u096f", + "\u096e", + "9", + "5", + "\u096b", + "\u0969", + "\u096c", + "\u0967", + null, + "0", + "\u096a", + "7", "6", null, - "\u096f", - null, - "9", - "\u096b", - "\u096a", - "3", - null, - "1", - "\u096d", - "\u096e", - "\u096c", - "\u0969", - "4", - "5", - "0", "2", - "7", - "\u0967", + null, + "8", + "3", "\u0968", + "\u096d", "\u0966", + "4", + "1", + null, "?\u0967\u0968\u0969" }; @@ -3543,36 +3539,31 @@ public final class KeyboardTextsTable { null, null, null, + null, + null, + null, "\u104a", null, - null, - null, - null, - null, - null, - null, "\u104b", null, null, null, + null, + null, + null, "\\", null, null, null, null, null, - null, - null, - null, - null, - null, - null, - null, + "\u104a", null, null, "!autoColumnOrder!9,\u104a,.,?,!,#,),(,/,;,...,',@,:,-,\\\",+,\\%,&", null, - "\u104a", + null, + null, null, null, null, @@ -3607,14 +3598,22 @@ public final class KeyboardTextsTable { null, null, null, + null, + null, + null, + null, + null, + null, + null, + null, "!autoColumnOrder!8,.,',#,),(,/,;,@,...,:,-,\\\",+,\\%,&" }; private static final String[] TEXTS_nb = { "nb", null, - "\u00e5,\u00e6,\u00e4,\u00e0,\u00e1,\u00e2,\u00e3,\u0101", "\u00f8,\u00f6,\u00f4,\u00f2,\u00f3,\u00f5,\u0153,\u014d", + "\u00e5,\u00e6,\u00e4,\u00e0,\u00e1,\u00e2,\u00e3,\u0101", "\u00fc,\u00fb,\u00f9,\u00fa,\u016b", "\u00e9,\u00e8,\u00ea,\u00eb,\u0119,\u0117,\u0113", null, @@ -3662,15 +3661,16 @@ public final class KeyboardTextsTable { null, null, null, - "\u00f6", - null, - null, + "\u00e6", null, null, "\u00f8", null, null, - "\u00e6", + null, + null, + "\u00f6", + null, null, null, "\u00e5", @@ -3692,6 +3692,9 @@ public final class KeyboardTextsTable { null, null, null, + null, + null, + null, "\u00e4" }; @@ -3720,43 +3723,40 @@ public final class KeyboardTextsTable { null, null, null, - "8", + "\u096f", + "\u096e", + "9", + "5", + "\u096b", + "\u0969", + "\u096c", + "\u0967", + null, + "0", + "\u096a", + "7", "6", null, - "\u096f", - null, - "9", - "\u096b", - "\u096a", - "3", - null, - "1", - "\u096d", - "\u096e", - "\u096c", - "\u0969", - "4", - "5", - "0", "2", - "7", - "\u0967", + null, + "8", + "3", "\u0968", + "\u096d", "\u0966", + "4", + "1", + null, "?\u0967\u0968\u0969", - null, "!autoColumnOrder!8,.,\\\\,',#,),(,/,;,@,:,-,\\\",+,\\%,&", + null, + null, "!autoColumnOrder!9,.,\\\\,?,!,#,),(,/,;,',@,:,-,\\\",+,\\%,&", null, null, null, null, null, - null, - null, - null, - null, - null, "\u0964", null, null, @@ -3780,16 +3780,14 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, "\u0964" }; private static final String[] TEXTS_nl = { "nl", null, - "\u00e1,\u00e4,\u00e2,\u00e0", "\u00f3,\u00f6", + "\u00e1,\u00e4,\u00e2,\u00e0", "\u00fa,\u00fc", "\u00e9,\u00eb,\u00ea,\u00e8", "\u00ed,\u00ef,\u00ec,\u00ee,\u012f,\u012b,\u0133", @@ -3798,8 +3796,8 @@ public final class KeyboardTextsTable { null, null, null, - "\u00f4,\u00f2,\u00f5,\u0153,\u00f8,\u014d", "\u00e6,\u00e3,\u00e5,\u0101", + "\u00f4,\u00f2,\u00f5,\u0153,\u00f8,\u014d", "\u00fb,\u00f9,\u016b", "\u0119,\u0117,\u0113" }; @@ -3807,8 +3805,8 @@ public final class KeyboardTextsTable { private static final String[] TEXTS_pl = { "pl", null, - "\u0105", "\u00f3", + "\u0105", null, "\u0119", null, @@ -3817,15 +3815,24 @@ public final class KeyboardTextsTable { "\u0107", null, "\u015b", - "\u00f6,\u00f4,\u00f2,\u00f5,\u0153,\u00f8,\u014d", "\u00e1,\u00e0,\u00e2,\u00e4,\u00e6,\u00e3,\u00e5,\u0101", + "\u00f6,\u00f4,\u00f2,\u00f5,\u0153,\u00f8,\u014d", null, "\u00e8,\u00e9,\u00ea,\u00eb,\u0117,\u0113", - null, "\u017c,\u017a", "\u0144", - "\u00df,\u0161", + null, "\u00e7,\u010d", + "\u00df,\u0161", + null, + null, + null, + null, + null, + null, + null, + null, + null, null, null, null, @@ -3849,17 +3856,6 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, "\u00f1", null, null, @@ -3872,14 +3868,25 @@ public final class KeyboardTextsTable { null, null, null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, "\u0142" }; private static final String[] TEXTS_pt = { "pt", null, - "\u00e1,\u00e3,\u00e0,\u00e2", "\u00f3,\u00f5,\u00f4", + "\u00e1,\u00e3,\u00e0,\u00e2", "\u00fa,\u00fc", "\u00e9,\u00ea", "\u00ed", @@ -3888,14 +3895,13 @@ public final class KeyboardTextsTable { "\u00e7", null, null, - "\u00f2,\u00f6,\u0153,\u00f8,\u014d,\u00ba", "\u00e4,\u00e5,\u00e6,\u00aa", + "\u00f2,\u00f6,\u0153,\u00f8,\u014d,\u00ba", "\u00f9,\u00fb,\u016b", "\u00e8,\u0119,\u0117,\u0113,\u00eb", + null, + null, "\u00ee,\u00ec,\u00ef,\u012f,\u012b", - null, - null, - null, "\u010d,\u0107", null, null, @@ -3971,21 +3977,26 @@ public final class KeyboardTextsTable { null, null, null, + null, + null, + null, + null, + null, + null, "\u00e7" }; private static final String[] TEXTS_rm = { "rm", null, - null, "\u00f2,\u00f3,\u00f6,\u00f4,\u00f5,\u0153,\u00f8" }; private static final String[] TEXTS_ro = { "ro", null, - "\u0103,\u00e2", null, + "\u0103,\u00e2", null, null, "\u00ee", @@ -3994,13 +4005,14 @@ public final class KeyboardTextsTable { null, null, "\u0219", - null, "\u00e3,\u00e0,\u00e1,\u00e4,\u00e6,\u00e5,\u0101", null, null, + null, + null, + null, "\u00ef,\u00ec,\u00ed,\u012f,\u012b", null, - null, "\u00df,\u015b,\u0161", null, null, @@ -4041,10 +4053,6 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, - null, - null, "\u021b" }; @@ -4096,19 +4104,21 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u0451", null, null, + "\u044b", + null, + null, null, - "\u0438", null, "\u0449", null, + "\u0438", + null, + null, null, - "\u044b", "\u044a", - null, "\u044d" }; @@ -4129,8 +4139,8 @@ public final class KeyboardTextsTable { private static final String[] TEXTS_sk = { "sk", null, - "\u00e1,\u00e4", "\u00f4,\u00f3", + "\u00e1,\u00e4", "\u00fa", "\u00e9", "\u00ed", @@ -4139,36 +4149,34 @@ public final class KeyboardTextsTable { "\u010d", null, "\u0161", - "\u00f6,\u00f2,\u00f5,\u0153,\u0151,\u00f8", "\u0101,\u00e0,\u00e2,\u00e3,\u00e5,\u00e6,\u0105", + "\u00f6,\u00f2,\u00f5,\u0153,\u0151,\u00f8", "\u016f,\u00fc,\u016b,\u0173,\u00f9,\u00fb,\u0171", "\u011b,\u0113,\u0117,\u00e8,\u00ea,\u00eb,\u0119", - "\u012b,\u012f,\u00ec,\u00ee,\u00ef,\u0131", "\u017e", "\u0148", - "\u00df,\u015b,\u015f", + "\u012b,\u012f,\u00ec,\u00ee,\u00ef,\u0131", "\u00e7,\u0107", + "\u00df,\u015b,\u015f", "!text/double_raqm_laqm", "!text/single_raqm_laqm", "\u00fd", null, null, - "\u010f", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, null, "\u017c,\u017a", null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, + "\u010f", null, null, null, @@ -4189,38 +4197,23 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u0165", null, null, null, - "\u013e,\u013a", + null, + null, + null, + null, + null, + null, + null, null, "\u0155", null, null, null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, + "\u013e,\u013a", null, null, null, @@ -4235,7 +4228,23 @@ public final class KeyboardTextsTable { "\u00ff", null, null, - "\u0159,\u0157", + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, null, null, null, @@ -4245,6 +4254,12 @@ public final class KeyboardTextsTable { null, null, null, + "\u0159,\u0157", + null, + null, + null, + null, + null, null, null, null, @@ -4287,11 +4302,11 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u017e", null, null, "\u0107", + null, "!text/double_raqm_laqm", "!text/single_raqm_laqm" }; @@ -4344,7 +4359,6 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u0450", null, null, @@ -4404,27 +4418,29 @@ public final class KeyboardTextsTable { null, null, null, - "\u0452", + null, + null, + null, + null, + null, null, "\u045b", null, null, + "\u0455", + null, + null, + null, + null, + null, + null, + "\u0452", null, null, null, null, "\u045d", - null, - null, - null, - null, - "\u0437", - null, - null, - null, - null, - null, - "\u0455" + "\u0437" }; private static final String[] TEXTS_sr_ZZ = { @@ -4444,7 +4460,6 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u017e,%", null, null, @@ -4454,6 +4469,20 @@ public final class KeyboardTextsTable { null, null, null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, "\u0111,%", null, null, @@ -4523,49 +4552,30 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - "\u0160alji", - null, - null, - null, - null, - null, - null, - null, - null, + "\u010cekaj", null, "Preth", + "Tra\u017ei", + null, + null, + "Gotov", + null, + "Idi", + null, null, - "Sled", - "\u010cekaj", "Pauza", null, null, null, - "Idi", - "Gotov", - "Tra\u017ei" + "Sled", + "\u0160alji" }; private static final String[] TEXTS_sv = { "sv", null, - "\u00e4,\u00e5", "\u00f6", + "\u00e4,\u00e5", null, "\u00e9", null, @@ -4574,8 +4584,8 @@ public final class KeyboardTextsTable { null, null, null, - "\u00f8,\u0153,\u00f3,\u00f2,\u00f4,\u00f5,\u014d", "\u00e6,\u00e1,\u00e0,\u00e2,\u0105,\u00e3", + "\u00f8,\u0153,\u00f3,\u00f2,\u00f4,\u00f5,\u014d", null, "\u00e8,\u00ea,\u00eb,\u0119", null, @@ -4613,15 +4623,16 @@ public final class KeyboardTextsTable { null, null, null, - "\u00f8,\u0153", - null, - null, + "\u00e4", null, null, "\u00f6", null, null, - "\u00e4", + null, + null, + "\u00f8,\u0153", + null, null, null, "\u00e5", @@ -4643,14 +4654,17 @@ public final class KeyboardTextsTable { null, null, null, + null, + null, + null, "\u00e6" }; private static final String[] TEXTS_sw = { "sw", null, - "\u00e0,\u00e1,\u00e2,\u00e4,\u00e6,\u00e3,\u00e5,\u0101", "\u00f4,\u00f6,\u00f2,\u00f3,\u0153,\u00f8,\u014d,\u00f5", + "\u00e0,\u00e1,\u00e2,\u00e4,\u00e6,\u00e3,\u00e5,\u0101", "\u00fb,\u00fc,\u00f9,\u00fa,\u016b", "\u00e8,\u00e9,\u00ea,\u00eb,\u0113", "\u00ee,\u00ef,\u00ed,\u012b,\u00ec", @@ -4664,7 +4678,6 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u00f1", null, null, @@ -4747,8 +4760,8 @@ public final class KeyboardTextsTable { private static final String[] TEXTS_tl = { "tl", null, - "\u00e1,\u00e0,\u00e4,\u00e2,\u00e3,\u00e5,\u0105,\u00e6,\u0101,\u00aa", "\u00f3,\u00f2,\u00f6,\u00f4,\u00f5,\u00f8,\u0153,\u014d,\u00ba", + "\u00e1,\u00e0,\u00e4,\u00e2,\u00e3,\u00e5,\u0105,\u00e6,\u0101,\u00aa", "\u00fa,\u00fc,\u00f9,\u00fb,\u016b", "\u00e9,\u00e8,\u00eb,\u00ea,\u0119,\u0117,\u0113", "\u00ed,\u00ef,\u00ec,\u00ee,\u012f,\u012b", @@ -4762,15 +4775,14 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u00f1,\u0144" }; private static final String[] TEXTS_tr = { "tr", null, - null, "\u00f6", + null, "\u00fc", null, "\u0131", @@ -4779,16 +4791,15 @@ public final class KeyboardTextsTable { "\u00e7", null, "\u015f", - "\u00f4,\u0153,\u00f2,\u00f3,\u00f5,\u00f8,\u014d", null, + "\u00f4,\u0153,\u00f2,\u00f3,\u00f5,\u00f8,\u014d", "\u00fb,\u00f9,\u00fa,\u016b", null, + null, + null, "\u00ee,\u00ef,\u00ec,\u00ed,\u012f,\u012b", - null, - null, - "\u00df,\u015b,\u0161", "\u0107,\u010d", - null, + "\u00df,\u015b,\u0161", null, null, null, @@ -4854,16 +4865,18 @@ public final class KeyboardTextsTable { null, null, null, + "\u0456", + null, null, null, - "\u0438", null, "\u0449", null, + "\u0438", + null, + null, null, - "\u0456", "\u044a", - null, "\u0454", null, null, @@ -4920,8 +4933,6 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, "\u0491", null, null, @@ -4930,14 +4941,18 @@ public final class KeyboardTextsTable { null, null, null, + null, + null, + null, + null, "\u0457" }; private static final String[] TEXTS_uz = { "uz", null, - "\u00e2,\u00e4,\u00e1", "\u00f6,\u00f4,\u0153,\u00f2,\u00f3,\u00f5,\u00f8,\u014d", + "\u00e2,\u00e4,\u00e1", "\u00fc,\u00fb,\u00f9,\u00fa,\u016b", "\u0259,\u00e9", "\u0131,\u00ee,\u00ef,\u00ec,\u00ed,\u012f,\u012b", @@ -4950,15 +4965,14 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u017e", "\u0148,\u00f1", null, null, null, null, - "\u00fd", null, + "\u00fd", null, null, null, @@ -4973,8 +4987,8 @@ public final class KeyboardTextsTable { private static final String[] TEXTS_vi = { "vi", null, - "\u00e0,\u00e1,\u1ea3,\u00e3,\u1ea1,\u0103,\u1eb1,\u1eaf,\u1eb3,\u1eb5,\u1eb7,\u00e2,\u1ea7,\u1ea5,\u1ea9,\u1eab,\u1ead", "\u00f2,\u00f3,\u1ecf,\u00f5,\u1ecd,\u00f4,\u1ed3,\u1ed1,\u1ed5,\u1ed7,\u1ed9,\u01a1,\u1edd,\u1edb,\u1edf,\u1ee1,\u1ee3", + "\u00e0,\u00e1,\u1ea3,\u00e3,\u1ea1,\u0103,\u1eb1,\u1eaf,\u1eb3,\u1eb5,\u1eb7,\u00e2,\u1ea7,\u1ea5,\u1ea9,\u1eab,\u1ead", "\u00f9,\u00fa,\u1ee7,\u0169,\u1ee5,\u01b0,\u1eeb,\u1ee9,\u1eed,\u1eef,\u1ef1", "\u00e8,\u00e9,\u1ebb,\u1ebd,\u1eb9,\u00ea,\u1ec1,\u1ebf,\u1ec3,\u1ec5,\u1ec7", "\u00ec,\u00ed,\u1ec9,\u0129,\u1ecb", @@ -4997,14 +5011,27 @@ public final class KeyboardTextsTable { "\u1ef3,\u00fd,\u1ef7,\u1ef9,\u1ef5", null, null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, "\u0111" }; private static final String[] TEXTS_zu = { "zu", null, - "\u00e0,\u00e1,\u00e2,\u00e4,\u00e6,\u00e3,\u00e5,\u0101", "\u00f3,\u00f4,\u00f6,\u00f2,\u0153,\u00f8,\u014d,\u00f5", + "\u00e0,\u00e1,\u00e2,\u00e4,\u00e6,\u00e3,\u00e5,\u0101", "\u00fa,\u00fb,\u00fc,\u00f9,\u016b", "\u00e9,\u00e8,\u00ea,\u00eb,\u0113", "\u00ed,\u00ee,\u00ef,\u012b,\u00ec", @@ -5018,15 +5045,14 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u00f1" }; private static final String[] TEXTS_zz = { "zz", null, - "\u00e0,\u00e1,\u00e2,\u00e3,\u00e4,\u00e5,\u00e6,\u0101,\u0103,\u0105,\u00aa", "\u00f2,\u00f3,\u00f4,\u00f5,\u00f6,\u00f8,\u014d,\u014f,\u0151,\u0153,\u00ba", + "\u00e0,\u00e1,\u00e2,\u00e3,\u00e4,\u00e5,\u00e6,\u0101,\u0103,\u0105,\u00aa", "\u00f9,\u00fa,\u00fb,\u00fc,\u0169,\u016b,\u016d,\u016f,\u0171,\u0173", "\u00e8,\u00e9,\u00ea,\u00eb,\u0113,\u0115,\u0117,\u0119,\u011b", "\u00ec,\u00ed,\u00ee,\u00ef,\u0129,\u012b,\u012d,\u012f,\u0131,\u0133", @@ -5039,17 +5065,16 @@ public final class KeyboardTextsTable { null, null, null, - null, "\u017a,\u017c,\u017e", "\u00f1,\u0144,\u0146,\u0148,\u0149,\u014b", null, null, null, null, + null, "\u00fd,\u0177,\u00ff,\u0133", null, null, - "\u010f,\u0111,\u00f0", null, null, null, @@ -5063,9 +5088,7 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, - null, + "\u010f,\u0111,\u00f0", null, null, null, @@ -5090,12 +5113,23 @@ public final class KeyboardTextsTable { null, null, null, - "\u013a,\u013c,\u013e,\u0140,\u0142", + null, + null, + null, + null, + null, + null, + null, null, "\u0155,\u0157,\u0159", null, null, null, + "\u013a,\u013c,\u013e,\u0140,\u0142", + null, + null, + null, + null, null, null, null, @@ -5144,25 +5178,16 @@ public final class KeyboardTextsTable { null, null, null, - null, - null, - null, - null, "\u0125", null, null, null, - null, - null, - "\u0135", + "\u0175", null, null, null, null, - null, - null, - null, - "\u0175" + "\u0135" }; private static final String[] TEXTS_DEFAULT = { @@ -5178,104 +5203,118 @@ public final class KeyboardTextsTable { EMPTY, "$", EMPTY, - "\u00f3,\u00f4,\u00f6,\u00f2,\u0153,\u00f8,\u014d,\u00f5", "\u00e0,\u00e1,\u00e2,\u00e4,\u00e6,\u00e3,\u00e5,\u0101", + "\u00f3,\u00f4,\u00f6,\u00f2,\u0153,\u00f8,\u014d,\u00f5", "\u00fa,\u00fb,\u00fc,\u00f9,\u016b", "\u00e9,\u00e8,\u00ea,\u00eb,\u0113", + EMPTY, + EMPTY, "\u00ed,\u00ee,\u00ef,\u012b,\u00ec", - EMPTY, - EMPTY, - "\u00df", "\u00e7", + "\u00df", "!text/double_laqm_raqm", "!text/single_laqm_raqm", EMPTY, - EMPTY, - EMPTY, - EMPTY, "9", + "8", EMPTY, EMPTY, "5", + "3", + "6", + "1", + EMPTY, + EMPTY, "4", EMPTY, EMPTY, EMPTY, - "7", - "8", - "6", - "3", EMPTY, EMPTY, EMPTY, EMPTY, - EMPTY, - "1", "2", + "7", "0", + EMPTY, + EMPTY, + EMPTY, "?123", - EMPTY, "!text/morekeys_tablet_punctuation", + EMPTY, + "\u00e4", "!text/morekeys_punctuation", - "\u00f8", - EMPTY, - ",", - EMPTY, "\u00f1", "\u00f6", EMPTY, - EMPTY, - "\u00e4", + ",", EMPTY, ".", - "\u00e5", + "\u00f8", EMPTY, + EMPTY, + EMPTY, + "\u00e5", "<", EMPTY, - "\u2039", - EMPTY, - "{", - EMPTY, - "]", - ")", - "\u00ab", "\u2264", - "[", - ">", - "}", - ",", + ")", "(", - "\u2020,\u2021,\u2605", - "!autoColumnOrder!8,\\,,?,!,#,!text/keyspec_right_parenthesis,!text/keyspec_left_parenthesis,/,;,',@,:,-,\",+,\\%,&", - "\u00e6", - EMPTY, - "\u00bf", "\u00bb", + "]", + EMPTY, + EMPTY, + "[", + "!autoColumnOrder!8,\\,,?,!,#,!text/keyspec_right_parenthesis,!text/keyspec_left_parenthesis,/,;,',@,:,-,\",+,\\%,&", + ",", + EMPTY, "\u2265", + "\u2020,\u2021,\u2605", + "}", + "\u2039", ".", + "\u00bf", + "{", + "\u00ab", + "\u00e6", + ">", "\u203a", - "%", + EMPTY, EMPTY, "\u266a,\u2665,\u2660,\u2666,\u2663", EMPTY, EMPTY, EMPTY, + EMPTY, + EMPTY, "?", - "\u00f1", - EMPTY, - EMPTY, - "!fixedColumnOrder!3,!text/keyspecs_right_parenthesis_more_keys", + "!autoColumnOrder!3,!text/keyspecs_right_parenthesis_more_keys", "\u2030", - "!fixedColumnOrder!3,!text/keyspecs_left_parenthesis_more_keys", - EMPTY, + "!autoColumnOrder!3,!text/keyspecs_left_parenthesis_more_keys", + "\u00f1", ";", + "%", EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, + "!string/label_wait_key", + EMPTY, + "!string/label_previous_key", + "!string/label_search_key", EMPTY, EMPTY, + "!string/label_done_key", + EMPTY, + "!string/label_go_key", + EMPTY, + EMPTY, + "!string/label_pause_key", + "!autoColumnOrder!8,\\,,?,!,#,!text/keyspec_right_parenthesis,!text/keyspec_left_parenthesis,/,;,',@,:,-,\",+,\\%,&", + EMPTY, + EMPTY, + "!string/label_next_key", "!string/label_send_key", EMPTY, EMPTY, @@ -5283,179 +5322,165 @@ public final class KeyboardTextsTable { EMPTY, EMPTY, EMPTY, - "!autoColumnOrder!8,\\,,?,!,#,!text/keyspec_right_parenthesis,!text/keyspec_left_parenthesis,/,;,',@,:,-,\",+,\\%,&", - EMPTY, - EMPTY, - "!string/label_previous_key", - EMPTY, - "!string/label_next_key", - "!string/label_wait_key", - "!string/label_pause_key", + "y", EMPTY, EMPTY, EMPTY, - "!string/label_go_key", - "!string/label_done_key", - "!string/label_search_key", EMPTY, "q", - "y", - "\u00a2,\u00a3,\u20ac,\u00a5,\u20b1", - "!fixedColumnOrder!3,!text/keyspec_left_single_angle_quote,!text/keyspec_less_than_equal,!text/keyspec_left_double_angle_quote", - "\u00a1,\u203d", "x", EMPTY, - EMPTY, - EMPTY, - "w", - EMPTY, - EMPTY, - EMPTY, - "!fixedColumnOrder!3,!text/keyspec_right_single_angle_quote,!text/keyspec_greater_than_equal,!text/keyspec_right_double_angle_quote", + "\u00a1,\u203d", "\u00b1", - EMPTY, - ";", - "!icon/action_redo|!code/action_redo", - EMPTY, - ":", - EMPTY, - ")", - EMPTY, - EMPTY, - "}", - EMPTY, - "\u2019,\u201a,\u2018", - EMPTY, - EMPTY, - "\u2018,\u201a,\u2019", - ">", - "\\\\", - EMPTY, - "@", - "5", - EMPTY, - "!icon/action_cut|!code/action_cut", - "\u201e,\u201c,\u201d", - "?,/", + "w", + "!fixedColumnOrder!3,!text/keyspec_left_single_angle_quote,!text/keyspec_less_than_equal,!text/keyspec_left_double_angle_quote", + "!fixedColumnOrder!3,!text/keyspec_right_single_angle_quote,!text/keyspec_greater_than_equal,!text/keyspec_right_double_angle_quote", + "\u00a2,\u00a3,\u20ac,\u00a5,\u20b1", EMPTY, EMPTY, EMPTY, - "!text/keyspec_right_single_angle_quote,!text/keyspec_left_single_angle_quote", EMPTY, - EMPTY, - "!text/keyspec_left_double_angle_quote,!text/keyspec_right_double_angle_quote", - "$,\u00a2,\u20ac,\u00a3,\u00a5,\u20b1", - "7", - EMPTY, - "^", - "!", - "6", - "3", - "\u2078,\u2088", - EMPTY, - "(", - "(,[,{,<", - "'", - EMPTY, - "!text/keyspec_less_than,!text/keyspec_left_curly_bracket,!text/keyspec_left_square_bracket", - "\u201a,\u2018,\u2019", - "\u2018,\u2019,\u201a", - "!fixedColumnOrder!4,!needsDividers!,!icon/action_switch_language|!code/action_switch_language,!icon/action_text_edit|!code/action_text_edit,!icon/action_clipboard_history|!code/action_clipboard_history,!icon/action_emoji|!code/action_emoji,!icon/previous_key|!code/key_action_previous,!icon/next_key|!code/key_action_next,!icon/action_undo|!code/action_undo,!icon/action_redo|!code/action_redo", - "\\%", - "!fixedColumnOrder!2,!hasLabels!,!text/keylabel_time_am,!text/keylabel_time_pm", - "123", - EMPTY, - ".com", - "~ [ <", - EMPTY, - "\\%", - EMPTY, - "!fixedColumnOrder!5,!text/double_quotes,!text/double_angle_quotes", - "4", - "= \\\\ <", - "\u201c,\u201e,\u201d", - EMPTY, - "=", - "\u2075,\u2085,\u215d", - "{", - "AM", - "\u2076,\u2086", - "-,\u2013,\u2014,_", "!hasLabels!,!text/label_next_key|!code/key_action_next", + "$", + "*", EMPTY, - "#", - "\u2074,\u2084", - "\u2079,\u2089", - "]", - EMPTY, - "@", - "!icon/action_select_all|!code/action_select_all", - "#", - "!fixedColumnOrder!4,!needsDividers!,!icon/action_switch_language|!code/action_switch_language,!icon/action_text_edit|!code/action_text_edit,!icon/action_clipboard_history|!code/action_clipboard_history,!icon/action_emoji|!code/action_emoji,!icon/action_undo|!code/action_undo,!icon/action_redo|!code/action_redo", - EMPTY, - "!text/keyspec_greater_than,!text/keyspec_right_curly_bracket,!text/keyspec_right_square_bracket", - EMPTY, - EMPTY, - "!icon/shortcut_key|!code/key_shortcut", - EMPTY, - "\uff0a\uff03", EMPTY, "!hasLabels!,.net,.org,.gov,.edu", - "&", - "!hasLabels!,!text/label_previous_key|!code/key_action_previous", + "\u2019,\u201a,\u2018", + "!", EMPTY, - "*", - "0", - EMPTY, - EMPTY, - "%", - EMPTY, - EMPTY, - EMPTY, - "\u201d,\u201e,\u201c", - EMPTY, - "1", - EMPTY, - "!icon/settings_key|!code/key_settings", - "<", - "!text/keyspec_right_double_angle_quote,!text/keyspec_left_double_angle_quote", - "!fixedColumnOrder!5,!text/single_quotes,!text/single_angle_quotes", - "\u00b3,\u2083,\u00be,\u215c", "|", EMPTY, EMPTY, + "!icon/action_select_all|!code/action_select_all", + EMPTY, + EMPTY, + EMPTY, + EMPTY, + "1", + EMPTY, + EMPTY, + "{", + "= \\\\ <", + "(,[,{,<", + "#", + EMPTY, + "4", + EMPTY, "2", - "8", - "!text/keyspec_left_single_angle_quote,!text/keyspec_right_single_angle_quote", - "!icon/action_undo|!code/action_undo", - "\u00b9,\u2081,\u00bd,\u2153,\u00bc,\u215b", - "\u00b2,\u2082,\u2154", - "$", - "\u2070,\u2080,\u207f,\u2205", - "$,\u20ac,\u00a3,\u00a5,\u00a2", - "!icon/action_copy|!code/action_copy", - "),],},>", - "*", - EMPTY, - "!icon/action_paste|!code/action_paste", - "&,|", - "!", - EMPTY, - EMPTY, - EMPTY, - EMPTY, - "\u201c,\u201d,\u201e", - "\"", - "\u2077,\u2087,\u215e", - EMPTY, - "[", - "9", - EMPTY, - EMPTY, - "+,=", "!fixedColumnOrder!6,!text/double_quotes,!text/single_quotes,!text/double_angle_quotes,!text/single_angle_quotes", + EMPTY, + EMPTY, + "<", + "!icon/action_paste|!code/action_paste", + "\u00b9,\u2081,\u00bd,\u2153,\u00bc,\u215b", + "!fixedColumnOrder!4,!needsDividers!,!icon/action_switch_language|!code/action_switch_language,!icon/action_text_edit|!code/action_text_edit,!icon/action_clipboard_history|!code/action_clipboard_history,!icon/action_emoji|!code/action_emoji,!icon/previous_key|!code/key_action_previous,!icon/next_key|!code/key_action_next,!icon/action_undo|!code/action_undo,!icon/action_redo|!code/action_redo", + "%", + "!", + "?,/", + "-,\u2013,\u2014,_", + EMPTY, + "!text/keyspec_left_single_angle_quote,!text/keyspec_right_single_angle_quote", + "@", + "\u201e,\u201c,\u201d", + "9", + ";", + EMPTY, + "0", + "\u2070,\u2080,\u207f,\u2205", + EMPTY, + "]", + "),],},>", + EMPTY, + "AM", + "\u2018,\u2019,\u201a", + "+,=", "PM", - EMPTY + EMPTY, + EMPTY, + "$,\u20ac,\u00a3,\u00a5,\u00a2", + "\u201a,\u2018,\u2019", + EMPTY, + "123", + EMPTY, + EMPTY, + EMPTY, + "'", + EMPTY, + "!text/keyspec_right_double_angle_quote,!text/keyspec_left_double_angle_quote", + EMPTY, + "~ [ <", + "=", + "!text/keyspec_greater_than,!text/keyspec_right_curly_bracket,!text/keyspec_right_square_bracket", + "\\%", + "!icon/shortcut_key|!code/key_shortcut", + "#", + EMPTY, + "&", + EMPTY, + "!fixedColumnOrder!4,!needsDividers!,!icon/action_switch_language|!code/action_switch_language,!icon/action_text_edit|!code/action_text_edit,!icon/action_clipboard_history|!code/action_clipboard_history,!icon/action_emoji|!code/action_emoji,!icon/action_undo|!code/action_undo,!icon/action_redo|!code/action_redo", + "\\\\", + "7", + "\u2075,\u2085,\u215d", + "!icon/action_undo|!code/action_undo", + EMPTY, + EMPTY, + ":", + "\u00b3,\u2083,\u00be,\u215c", + "!text/keyspec_right_single_angle_quote,!text/keyspec_left_single_angle_quote", + "\u2079,\u2089", + "\\%", + "!icon/action_cut|!code/action_cut", + EMPTY, + "6", + "$,\u00a2,\u20ac,\u00a3,\u00a5,\u20b1", + "\u2074,\u2084", + "!icon/settings_key|!code/key_settings", + "!icon/action_copy|!code/action_copy", + "!text/keyspec_left_double_angle_quote,!text/keyspec_right_double_angle_quote", + "3", + "^", + "!fixedColumnOrder!5,!text/double_quotes,!text/double_angle_quotes", + ">", + "*", + "\u00b2,\u2082,\u2154", + ")", + "(", + EMPTY, + EMPTY, + "!fixedColumnOrder!5,!text/single_quotes,!text/single_angle_quotes", + "&,|", + "!text/keyspec_less_than,!text/keyspec_left_curly_bracket,!text/keyspec_left_square_bracket", + "}", + EMPTY, + ".com", + "\"", + "\u201c,\u201d,\u201e", + EMPTY, + "!fixedColumnOrder!2,!hasLabels!,!text/keylabel_time_am,!text/keylabel_time_pm", + EMPTY, + "!hasLabels!,!text/label_previous_key|!code/key_action_previous", + "[", + EMPTY, + EMPTY, + EMPTY, + "\u201c,\u201e,\u201d", + EMPTY, + "\u2076,\u2086", + "\u2077,\u2087,\u215e", + "\u201d,\u201e,\u201c", + "8", + "\u2018,\u201a,\u2019", + "@", + "5", + EMPTY, + EMPTY, + EMPTY, + "\u2078,\u2088", + EMPTY, + "!icon/action_redo|!code/action_redo", + EMPTY, + "\uff0a\uff03" }; diff --git a/java/src/org/futo/inputmethod/keyboard/internal/MoreKeySpec.java b/java/src/org/futo/inputmethod/keyboard/internal/MoreKeySpec.java index bca1796d4..7cde877d4 100644 --- a/java/src/org/futo/inputmethod/keyboard/internal/MoreKeySpec.java +++ b/java/src/org/futo/inputmethod/keyboard/internal/MoreKeySpec.java @@ -84,9 +84,7 @@ public final class MoreKeySpec { @Nonnull public Key buildKey(final int x, final int y, final int labelFlags, @Nonnull final KeyboardParams params) { - return new Key(mLabel, mIconId, mCode, mOutputText, null /* hintLabel */, labelFlags, - Key.BACKGROUND_TYPE_NORMAL, x, y, params.mDefaultKeyWidth, params.mDefaultRowHeight, - params.mHorizontalGap, params.mVerticalGap, Key.ACTION_FLAGS_NO_KEY_PREVIEW); + return Key.buildKeyForMoreKeySpec(this, x, y, labelFlags, params); } @Override diff --git a/java/src/org/futo/inputmethod/keyboard/internal/TimerHandler.java b/java/src/org/futo/inputmethod/keyboard/internal/TimerHandler.java index 2012bfc0f..fdaae7d13 100644 --- a/java/src/org/futo/inputmethod/keyboard/internal/TimerHandler.java +++ b/java/src/org/futo/inputmethod/keyboard/internal/TimerHandler.java @@ -137,7 +137,7 @@ public final class TimerHandler extends LeakGuardHandlerWrapper @Override public void startTypingStateTimer(@Nonnull final Key typedKey) { - if (typedKey.isModifier() || typedKey.altCodeWhileTyping()) { + if (typedKey.isModifier() || typedKey.getAltCodeWhileTyping()) { return; } diff --git a/java/src/org/futo/inputmethod/latin/uix/BasicThemeProvider.kt b/java/src/org/futo/inputmethod/latin/uix/BasicThemeProvider.kt index 7cecf8724..053e22c7d 100644 --- a/java/src/org/futo/inputmethod/latin/uix/BasicThemeProvider.kt +++ b/java/src/org/futo/inputmethod/latin/uix/BasicThemeProvider.kt @@ -7,26 +7,23 @@ import android.graphics.drawable.LayerDrawable import android.graphics.drawable.ShapeDrawable import android.graphics.drawable.StateListDrawable import android.graphics.drawable.shapes.RoundRectShape +import android.os.Build import android.util.Log import android.util.TypedValue import androidx.annotation.ColorInt import androidx.appcompat.content.res.AppCompatResources -import androidx.compose.material3.ColorScheme -import androidx.compose.material3.dynamicLightColorScheme import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import androidx.core.graphics.ColorUtils import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.booleanPreferencesKey import androidx.datastore.preferences.core.floatPreferencesKey -import com.google.android.material.color.DynamicColors import org.futo.inputmethod.keyboard.internal.KeyboardIconsSet import org.futo.inputmethod.latin.R import org.futo.inputmethod.latin.uix.actions.AllActions import org.futo.inputmethod.latin.uix.actions.AllActionsMap -import org.futo.inputmethod.latin.uix.theme.DarkColorScheme +import org.futo.inputmethod.v2keyboard.KeyVisualStyle import kotlin.math.roundToInt val KeyBordersSetting = SettingsKey(booleanPreferencesKey("keyBorders"), true) @@ -53,8 +50,6 @@ class BasicThemeProvider(val context: Context, val colorScheme: KeyboardColorSch override val moreKeysTextColor: Int override val moreKeysKeyboardBackground: Drawable - override val popupKey: Drawable - override val actionPopupKey: Drawable private val colors: HashMap = HashMap() override fun getColor(i: Int): Int? { @@ -82,6 +77,11 @@ class BasicThemeProvider(val context: Context, val colorScheme: KeyboardColorSch return keyboardHeight } + val keyStyles: Map + override fun getKeyStyleDescriptor(visualStyle: KeyVisualStyle): VisualStyleDescriptor { + return keyStyles[visualStyle]!! + } + private fun dp(dp: Dp): Float { return TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, @@ -124,6 +124,17 @@ class BasicThemeProvider(val context: Context, val colorScheme: KeyboardColorSch addState(stateSet, drawable) } + private fun makeVisualStyle(background: Int, foreground: Int, highlight: Int, roundedness: Dp): VisualStyleDescriptor { + val bg = coloredRoundedRectangle(background, dp(roundedness)) + val bgHighlight = coloredRoundedRectangle(highlight, dp(roundedness)) + return VisualStyleDescriptor( + backgroundDrawable = bg, + foregroundColor = foreground, + + backgroundDrawablePressed = LayerDrawable(arrayOf(bg, bgHighlight)) + ) + } + val expertMode: Boolean val keyBorders: Boolean val showKeyHints: Boolean @@ -272,44 +283,6 @@ class BasicThemeProvider(val context: Context, val colorScheme: KeyboardColorSch keyboardBackground = coloredRectangle(primaryKeyboardColor) - keyBackground = StateListDrawable().apply { - addStateWithHighlightLayerOnPressed(highlight, intArrayOf(android.R.attr.state_active), - coloredRoundedRectangle(enterKeyBackground, dp(128.dp)), - cornerRadius = 128.dp - ) - - addStateWithHighlightLayerOnPressed(highlight, intArrayOf(android.R.attr.state_checkable, android.R.attr.state_checked), - coloredRoundedRectangle(colorScheme.secondaryContainer.toArgb(), dp(8.dp)) - ) - - addStateWithHighlightLayerOnPressed(highlight, intArrayOf(android.R.attr.state_checkable), - if(keyBorders) { - coloredRoundedRectangle(keyColor, dp(8.dp)) - } else { - coloredRectangle(transparent) - } - ) - - addStateWithHighlightLayerOnPressed(highlight, intArrayOf(android.R.attr.state_first), - if(keyBorders) { - coloredRoundedRectangle(functionalKeyColor, dp(8.dp)) - } else { - coloredRectangle(transparent) - } - ) - - addStateWithHighlightLayerOnPressed(highlight, intArrayOf(android.R.attr.state_empty), - coloredRectangle(transparent) - ) - - addStateWithHighlightLayerOnPressed(highlight, intArrayOf(), - if(keyBorders) { - coloredRoundedRectangle(keyColor, dp(8.dp)) - } else { - coloredRectangle(transparent) - } - ) - } val spaceCornerRadius = if(keyBorders) { 8.dp @@ -317,6 +290,99 @@ class BasicThemeProvider(val context: Context, val colorScheme: KeyboardColorSch 48.dp } + keyStyles = mapOf( + KeyVisualStyle.Action to VisualStyleDescriptor( + backgroundDrawable = coloredRoundedRectangle(colorScheme.primary.toArgb(), dp(128.dp)), + foregroundColor = colorScheme.onPrimary.toArgb(), + + backgroundDrawablePressed = coloredRoundedRectangle(colorScheme.secondaryContainer.toArgb(), dp(128.dp)), + foregroundColorPressed = colorScheme.onSecondaryContainer.toArgb() + ), + + KeyVisualStyle.Normal to if(keyBorders) { + makeVisualStyle( + colorScheme.backgroundContainer.toArgb(), + colorScheme.onBackgroundContainer.toArgb(), + highlight, + 8.dp + ) + } else { + makeVisualStyle( + transparent, + onBackground, + highlight, + 8.dp + ) + }, + + KeyVisualStyle.MoreKey to VisualStyleDescriptor( + backgroundDrawable = coloredRoundedRectangle(primaryContainer, dp(24.dp)), + foregroundColor = onPrimaryContainer, + + backgroundDrawablePressed = coloredRoundedRectangle(onPrimaryContainer, dp(24.dp)), + foregroundColorPressed = primaryContainer + ), + + KeyVisualStyle.Functional to if(keyBorders) { + makeVisualStyle( + colorScheme.backgroundContainerDim.toArgb(), + colorScheme.onBackgroundContainer.toArgb(), + highlight, + 8.dp + ) + } else { + makeVisualStyle( + transparent, + onBackground, + highlight, + 8.dp + ) + }, + + KeyVisualStyle.StickyOff to if(keyBorders) { + makeVisualStyle( + colorScheme.backgroundContainerDim.toArgb(), + colorScheme.onBackgroundContainer.toArgb(), + highlight, + 8.dp + ) + } else { + makeVisualStyle( + transparent, + onBackground, + highlight, + 8.dp + ) + }, + + KeyVisualStyle.NoBackground to makeVisualStyle(transparent, onBackground, highlight, 8.dp), + + KeyVisualStyle.StickyOn to makeVisualStyle( + colorScheme.secondaryContainer.toArgb(), + colorScheme.onSecondaryContainer.toArgb(), + highlight, + 8.dp + ), + + KeyVisualStyle.Spacebar to when { + keyBorders -> makeVisualStyle(keyColor, onKeyColor, highlight, spaceCornerRadius) + expertMode -> makeVisualStyle( + colorScheme.outline.copy(alpha = 0.1f).toArgb(), + onKeyColor, + highlight, + spaceCornerRadius + ) + else -> makeVisualStyle( + highlight, + onKeyColor, + highlight, + spaceCornerRadius + ) + } + ) + + keyBackground = keyStyles[KeyVisualStyle.Normal]!!.backgroundDrawable!! + val spaceDrawable = if(keyBorders) { coloredRoundedRectangle(keyColor, dp(spaceCornerRadius)) } else if(expertMode) { @@ -355,19 +421,11 @@ class BasicThemeProvider(val context: Context, val colorScheme: KeyboardColorSch } moreKeysTextColor = onPrimaryContainer - moreKeysKeyboardBackground = coloredRoundedRectangle(primaryContainer, dp(8.dp)) - popupKey = StateListDrawable().apply { - addStateWithHighlightLayerOnPressed(primary, intArrayOf(), - coloredRoundedRectangle(primaryContainer, dp(8.dp)) - ) + moreKeysKeyboardBackground = coloredRoundedRectangle(primaryContainer, dp(28.dp)).apply { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + val padding = dp(4.dp).roundToInt() + setPadding(padding, padding, padding, padding) + } } - actionPopupKey = StateListDrawable().apply { - addStateWithHighlightLayerOnPressed(primary, intArrayOf(), - coloredRoundedRectangle(primaryContainer, dp(128.dp)), - 128.dp - ) - } - } - } \ No newline at end of file diff --git a/java/src/org/futo/inputmethod/latin/uix/DynamicThemeProvider.kt b/java/src/org/futo/inputmethod/latin/uix/DynamicThemeProvider.kt index 929a6b51a..c550f1a83 100644 --- a/java/src/org/futo/inputmethod/latin/uix/DynamicThemeProvider.kt +++ b/java/src/org/futo/inputmethod/latin/uix/DynamicThemeProvider.kt @@ -3,6 +3,24 @@ package org.futo.inputmethod.latin.uix import android.content.res.TypedArray import android.graphics.drawable.Drawable import androidx.annotation.ColorInt +import org.futo.inputmethod.v2keyboard.KeyVisualStyle + +/** Visual style descriptor for a key */ +data class VisualStyleDescriptor( + /** Key background drawable when not pressed */ + val backgroundDrawable: Drawable?, + + /** Key foreground label/icon color when not pressed */ + @ColorInt + val foregroundColor: Int, + + /** Key background drawable when pressed */ + val backgroundDrawablePressed: Drawable? = backgroundDrawable, + + /** Key foreground label/icon color when pressed */ + @ColorInt + val foregroundColorPressed: Int = foregroundColor +) interface DynamicThemeProvider { val primaryKeyboardColor: Int @@ -16,8 +34,6 @@ interface DynamicThemeProvider { val moreKeysTextColor: Int val moreKeysKeyboardBackground: Drawable - val popupKey: Drawable - val actionPopupKey: Drawable @ColorInt fun getColor(i: Int): Int? @@ -28,6 +44,8 @@ interface DynamicThemeProvider { fun getKeyboardHeightMultiplier(): Float + fun getKeyStyleDescriptor(visualStyle: KeyVisualStyle): VisualStyleDescriptor + companion object { @ColorInt fun getColorOrDefault(i: Int, @ColorInt default: Int, keyAttr: TypedArray, provider: DynamicThemeProvider?): Int { diff --git a/java/src/org/futo/inputmethod/v2keyboard/BaseKey.kt b/java/src/org/futo/inputmethod/v2keyboard/BaseKey.kt index d3619a48b..694c8e4a8 100644 --- a/java/src/org/futo/inputmethod/v2keyboard/BaseKey.kt +++ b/java/src/org/futo/inputmethod/v2keyboard/BaseKey.kt @@ -3,6 +3,7 @@ package org.futo.inputmethod.v2keyboard import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.builtins.serializer +import org.futo.inputmethod.keyboard.KeyConsts import org.futo.inputmethod.keyboard.KeyboardId import org.futo.inputmethod.keyboard.internal.KeySpecParser import org.futo.inputmethod.keyboard.internal.KeyboardParams @@ -10,8 +11,6 @@ import org.futo.inputmethod.keyboard.internal.MoreKeySpec import org.futo.inputmethod.latin.common.Constants import org.futo.inputmethod.latin.common.StringUtils -typealias KeyJ = org.futo.inputmethod.keyboard.Key - /** * Width tokens for keys. Rather than explicitly specifying a width in percentage as is common in * other layout systems, we instead use width tokens, which eliminates the need to explicitly @@ -80,12 +79,12 @@ enum class KeyWidth { internal fun computeMoreKeysFlags(moreKeys: Array, params: KeyboardParams): Int { // Get maximum column order number and set a relevant mode value. var moreKeysColumnAndFlags = - (KeyJ.MORE_KEYS_MODE_MAX_COLUMN_WITH_AUTO_ORDER + (KeyConsts.MORE_KEYS_MODE_MAX_COLUMN_WITH_AUTO_ORDER or params.mMaxMoreKeysKeyboardColumn) var value: Int if ((MoreKeySpec.getIntValue( moreKeys, - KeyJ.MORE_KEYS_AUTO_COLUMN_ORDER, + KeyConsts.MORE_KEYS_AUTO_COLUMN_ORDER, -1 ).also { value = it @@ -93,12 +92,12 @@ internal fun computeMoreKeysFlags(moreKeys: Array, params: KeyboardParam ) { // Override with fixed column order number and set a relevant mode value. moreKeysColumnAndFlags = - (KeyJ.MORE_KEYS_MODE_FIXED_COLUMN_WITH_AUTO_ORDER - or (value and KeyJ.MORE_KEYS_COLUMN_NUMBER_MASK)) + (KeyConsts.MORE_KEYS_MODE_FIXED_COLUMN_WITH_AUTO_ORDER + or (value and KeyConsts.MORE_KEYS_COLUMN_NUMBER_MASK)) } if ((MoreKeySpec.getIntValue( moreKeys, - KeyJ.MORE_KEYS_FIXED_COLUMN_ORDER, + KeyConsts.MORE_KEYS_FIXED_COLUMN_ORDER, -1 ).also { value = it @@ -106,43 +105,43 @@ internal fun computeMoreKeysFlags(moreKeys: Array, params: KeyboardParam ) { // Override with fixed column order number and set a relevant mode value. moreKeysColumnAndFlags = - (KeyJ.MORE_KEYS_MODE_FIXED_COLUMN_WITH_FIXED_ORDER - or (value and KeyJ.MORE_KEYS_COLUMN_NUMBER_MASK)) + (KeyConsts.MORE_KEYS_MODE_FIXED_COLUMN_WITH_FIXED_ORDER + or (value and KeyConsts.MORE_KEYS_COLUMN_NUMBER_MASK)) } if (MoreKeySpec.getBooleanValue( moreKeys, - KeyJ.MORE_KEYS_HAS_LABELS + KeyConsts.MORE_KEYS_HAS_LABELS ) ) { moreKeysColumnAndFlags = - moreKeysColumnAndFlags or KeyJ.MORE_KEYS_FLAGS_HAS_LABELS + moreKeysColumnAndFlags or KeyConsts.MORE_KEYS_FLAGS_HAS_LABELS } if (MoreKeySpec.getBooleanValue( moreKeys, - KeyJ.MORE_KEYS_NEEDS_DIVIDERS + KeyConsts.MORE_KEYS_NEEDS_DIVIDERS ) ) { moreKeysColumnAndFlags = - moreKeysColumnAndFlags or KeyJ.MORE_KEYS_FLAGS_NEEDS_DIVIDERS + moreKeysColumnAndFlags or KeyConsts.MORE_KEYS_FLAGS_NEEDS_DIVIDERS } if (MoreKeySpec.getBooleanValue( moreKeys, - KeyJ.MORE_KEYS_NO_PANEL_AUTO_MORE_KEY + KeyConsts.MORE_KEYS_NO_PANEL_AUTO_MORE_KEY ) ) { moreKeysColumnAndFlags = - moreKeysColumnAndFlags or KeyJ.MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY + moreKeysColumnAndFlags or KeyConsts.MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY } return moreKeysColumnAndFlags } internal fun filterMoreKeysFlags(moreKeys: List): List = moreKeys.filter { - !it.startsWith(KeyJ.MORE_KEYS_AUTO_COLUMN_ORDER) && - !it.startsWith(KeyJ.MORE_KEYS_FIXED_COLUMN_ORDER) && - !it.startsWith(KeyJ.MORE_KEYS_HAS_LABELS) && - !it.startsWith(KeyJ.MORE_KEYS_NEEDS_DIVIDERS) && - !it.startsWith(KeyJ.MORE_KEYS_NO_PANEL_AUTO_MORE_KEY) + !it.startsWith(KeyConsts.MORE_KEYS_AUTO_COLUMN_ORDER) && + !it.startsWith(KeyConsts.MORE_KEYS_FIXED_COLUMN_ORDER) && + !it.startsWith(KeyConsts.MORE_KEYS_HAS_LABELS) && + !it.startsWith(KeyConsts.MORE_KEYS_NEEDS_DIVIDERS) && + !it.startsWith(KeyConsts.MORE_KEYS_NO_PANEL_AUTO_MORE_KEY) } /** @@ -165,10 +164,15 @@ enum class MoreKeyMode( */ OnlyFromKeyspec(true, false, false), + /** + * Only automatically insert morekeys from coord, not keyspec shortcut. + */ + OnlyFromCoord(false, true, true), + /** * Do not automatically insert any morekeys. */ - OnlyExplicit(false, false, false) + OnlyExplicit(false, false, false), } private fun Int.and(other: Boolean): Int { @@ -190,14 +194,14 @@ data class LabelFlags( val autoXScale: Boolean = false, ) { fun getValue(): Int = - KeyJ.LABEL_FLAGS_ALIGN_LABEL_OFF_CENTER.and(alignLabelOffCenter) or - KeyJ.LABEL_FLAGS_ALIGN_HINT_LABEL_TO_BOTTOM.and(alignHintLabelToBottom) or - KeyJ.LABEL_FLAGS_ALIGN_ICON_TO_BOTTOM.and(alignIconToBottom) or - KeyJ.LABEL_FLAGS_HAS_HINT_LABEL.and(hasHintLabel) or - KeyJ.LABEL_FLAGS_FOLLOW_KEY_LABEL_RATIO.and(followKeyLabelRatio) or - KeyJ.LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO.and(followKeyLetterRatio) or - KeyJ.LABEL_FLAGS_FOLLOW_KEY_LARGE_LETTER_RATIO.and(followKeyLargeLetterRatio) or - KeyJ.LABEL_FLAGS_AUTO_X_SCALE.and(autoXScale) + KeyConsts.LABEL_FLAGS_ALIGN_LABEL_OFF_CENTER.and(alignLabelOffCenter) or + KeyConsts.LABEL_FLAGS_ALIGN_HINT_LABEL_TO_BOTTOM.and(alignHintLabelToBottom) or + KeyConsts.LABEL_FLAGS_ALIGN_ICON_TO_BOTTOM.and(alignIconToBottom) or + KeyConsts.LABEL_FLAGS_HAS_HINT_LABEL.and(hasHintLabel) or + KeyConsts.LABEL_FLAGS_FOLLOW_KEY_LABEL_RATIO.and(followKeyLabelRatio) or + KeyConsts.LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO.and(followKeyLetterRatio) or + KeyConsts.LABEL_FLAGS_FOLLOW_KEY_LARGE_LETTER_RATIO.and(followKeyLargeLetterRatio) or + KeyConsts.LABEL_FLAGS_AUTO_X_SCALE.and(autoXScale) } /** @@ -583,20 +587,14 @@ enum class KeyVisualStyle { * the same as [Normal] (key borders enabled) or a * fully rounded rectangle (key borders disabled) */ - Spacebar -} + Spacebar, -fun KeyVisualStyle.toBackgroundTypeInt(): Int = when(this) { - KeyVisualStyle.Normal -> KeyJ.BACKGROUND_TYPE_NORMAL - KeyVisualStyle.NoBackground -> KeyJ.BACKGROUND_TYPE_EMPTY - KeyVisualStyle.Functional -> KeyJ.BACKGROUND_TYPE_FUNCTIONAL - KeyVisualStyle.StickyOff -> KeyJ.BACKGROUND_TYPE_STICKY_OFF - KeyVisualStyle.StickyOn -> KeyJ.BACKGROUND_TYPE_STICKY_ON - KeyVisualStyle.Action -> KeyJ.BACKGROUND_TYPE_ACTION - KeyVisualStyle.Spacebar -> KeyJ.BACKGROUND_TYPE_SPACEBAR + /** + * Visual style for moreKeys + */ + MoreKey, } - /** * An empty gap in place of a key */ diff --git a/java/src/org/futo/inputmethod/v2keyboard/KeySpecShortcuts.kt b/java/src/org/futo/inputmethod/v2keyboard/KeySpecShortcuts.kt index 90df7502d..eaa12c0e6 100644 --- a/java/src/org/futo/inputmethod/v2keyboard/KeySpecShortcuts.kt +++ b/java/src/org/futo/inputmethod/v2keyboard/KeySpecShortcuts.kt @@ -16,6 +16,7 @@ val KeySpecShortcuts = mapOf( "0" to listOf("keyspec_symbols_0", "additional_morekeys_symbols_0", "morekeys_symbols_0"), ";" to listOf("keyspec_symbols_semicolon", "morekeys_symbols_semicolon"), "!" to listOf("!", "morekeys_exclamation"), + "+" to listOf("+", "morekeys_plus"), "?" to listOf("keyspec_symbols_question", "morekeys_question"), "\"" to listOf("\"", "morekeys_double_quote"), "\'" to listOf("\'", "morekeys_single_quote"), diff --git a/java/src/org/futo/inputmethod/v2keyboard/LayoutEngine.kt b/java/src/org/futo/inputmethod/v2keyboard/LayoutEngine.kt index 7e5b62408..4ff4b0460 100644 --- a/java/src/org/futo/inputmethod/v2keyboard/LayoutEngine.kt +++ b/java/src/org/futo/inputmethod/v2keyboard/LayoutEngine.kt @@ -3,9 +3,7 @@ package org.futo.inputmethod.v2keyboard import android.content.Context import android.view.ContextThemeWrapper import androidx.compose.ui.unit.Dp -import org.futo.inputmethod.keyboard.Key.ACTION_FLAGS_ENABLE_LONG_PRESS -import org.futo.inputmethod.keyboard.Key.ACTION_FLAGS_IS_REPEATABLE -import org.futo.inputmethod.keyboard.Key.ACTION_FLAGS_NO_KEY_PREVIEW +import org.futo.inputmethod.keyboard.KeyConsts import org.futo.inputmethod.keyboard.internal.KeyboardLayoutElement import org.futo.inputmethod.keyboard.internal.KeyboardParams import org.futo.inputmethod.latin.R @@ -458,9 +456,9 @@ data class LayoutEngine( return - val actionsFlags = if(!data.showPopup) { ACTION_FLAGS_NO_KEY_PREVIEW } else { 0 } or - if(data.longPressEnabled) { ACTION_FLAGS_ENABLE_LONG_PRESS } else { 0 } or - if(data.repeatable) { ACTION_FLAGS_IS_REPEATABLE } else { 0 } + val actionsFlags = if(!data.showPopup) { KeyConsts.ACTION_FLAGS_NO_KEY_PREVIEW } else { 0 } or + if(data.longPressEnabled) { KeyConsts.ACTION_FLAGS_ENABLE_LONG_PRESS } else { 0 } or + if(data.repeatable) { KeyConsts.ACTION_FLAGS_IS_REPEATABLE } else { 0 } val verticalGapForKey = when { keyboard.rowHeightMode.clampHeight && height > layoutParams.standardRowHeight -> @@ -471,25 +469,23 @@ data class LayoutEngine( } + verticalGapPx val key = org.futo.inputmethod.keyboard.Key( - data.label, - data.icon, - data.code, - data.outputText, - data.hint.ifEmpty { null }, - data.labelFlags, - data.style.toBackgroundTypeInt(), - x, - y, - width, - height, - horizontalGapPx.roundToInt(), - verticalGapForKey.roundToInt(), - actionsFlags + code = data.code, + label = data.label, + width = width - horizontalGapPx.roundToInt(), + height = height - verticalGapForKey.roundToInt(), + iconId = data.icon, + x = x, + y = y, + actionFlags = actionsFlags, + horizontalGap = horizontalGapPx.roundToInt(), + verticalGap = verticalGapForKey.roundToInt(), + labelFlags = data.labelFlags, + moreKeys = data.moreKeys, + moreKeysColumnAndFlags = data.moreKeyFlags, + visualStyle = data.style ) - val key2 = org.futo.inputmethod.keyboard.Key(key, data.moreKeyFlags, data.moreKeys.toTypedArray()) - - params.onAddKey(key2) + params.onAddKey(key) } private fun addRow(row: List, x: Float, y: Int, height: Int) {