identify keyboard icons by name only

re-work KeyboardIconsSet
also fixes a recent regression where some icons are not displayed
This commit is contained in:
Helium314 2024-05-12 18:08:15 +02:00
parent 789b76b790
commit 3862d1e9b2
12 changed files with 158 additions and 265 deletions

View file

@ -26,8 +26,6 @@ import helium314.keyboard.latin.utils.PopupKeysUtilsKt;
import java.util.Arrays; import java.util.Arrays;
import java.util.Locale; import java.util.Locale;
import static helium314.keyboard.keyboard.internal.KeyboardIconsSet.ICON_UNDEFINED;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -80,7 +78,7 @@ public class Key implements Comparable<Key> {
public static final int LABEL_FLAGS_DISABLE_ADDITIONAL_POPUP_KEYS = 0x80000000; public static final int LABEL_FLAGS_DISABLE_ADDITIONAL_POPUP_KEYS = 0x80000000;
/** Icon to display instead of a label. Icon takes precedence over a label */ /** Icon to display instead of a label. Icon takes precedence over a label */
private final int mIconId; @NonNull private final String mIconName;
/** Width of the key, excluding the gap */ /** Width of the key, excluding the gap */
private final int mWidth; private final int mWidth;
@ -156,29 +154,29 @@ public class Key implements Comparable<Key> {
public final String mOutputText; public final String mOutputText;
public final int mAltCode; public final int mAltCode;
/** Icon for disabled state */ /** Icon for disabled state */
public final int mDisabledIconId; public final String mDisabledIconName;
/** The visual insets */ /** The visual insets */
public final int mVisualInsetsLeft; public final int mVisualInsetsLeft;
public final int mVisualInsetsRight; public final int mVisualInsetsRight;
private OptionalAttributes(final String outputText, final int altCode, private OptionalAttributes(final String outputText, final int altCode,
final int disabledIconId, final int visualInsetsLeft, final int visualInsetsRight) { final String disabledIconName, final int visualInsetsLeft, final int visualInsetsRight) {
mOutputText = outputText; mOutputText = outputText;
mAltCode = altCode; mAltCode = altCode;
mDisabledIconId = disabledIconId; mDisabledIconName = disabledIconName;
mVisualInsetsLeft = visualInsetsLeft; mVisualInsetsLeft = visualInsetsLeft;
mVisualInsetsRight = visualInsetsRight; mVisualInsetsRight = visualInsetsRight;
} }
@Nullable @Nullable
public static OptionalAttributes newInstance(final String outputText, final int altCode, public static OptionalAttributes newInstance(final String outputText, final int altCode,
final int disabledIconId, final int visualInsetsLeft, final int visualInsetsRight) { final String disabledIconName, final int visualInsetsLeft, final int visualInsetsRight) {
if (outputText == null && altCode == KeyCode.NOT_SPECIFIED if (outputText == null && altCode == KeyCode.NOT_SPECIFIED
&& disabledIconId == ICON_UNDEFINED && visualInsetsLeft == 0 && disabledIconName.equals(KeyboardIconsSet.NAME_UNDEFINED) && visualInsetsLeft == 0
&& visualInsetsRight == 0) { && visualInsetsRight == 0) {
return null; return null;
} }
return new OptionalAttributes(outputText, altCode, disabledIconId, visualInsetsLeft, return new OptionalAttributes(outputText, altCode, disabledIconName, visualInsetsLeft,
visualInsetsRight); visualInsetsRight);
} }
} }
@ -193,7 +191,7 @@ public class Key implements Comparable<Key> {
/** /**
* Constructor for a key on <code>PopupKeyKeyboard</code> and on <code>MoreSuggestions</code>. * Constructor for a key on <code>PopupKeyKeyboard</code> and on <code>MoreSuggestions</code>.
*/ */
public Key(@Nullable final String label, final int iconId, final int code, public Key(@Nullable final String label, final String iconName, final int code,
@Nullable final String outputText, @Nullable final String hintLabel, @Nullable final String outputText, @Nullable final String hintLabel,
final int labelFlags, final int backgroundType, final int x, final int y, 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 width, final int height, final int horizontalGap, final int verticalGap) {
@ -210,10 +208,10 @@ public class Key implements Comparable<Key> {
mPopupKeysColumnAndFlags = 0; mPopupKeysColumnAndFlags = 0;
mLabel = label; mLabel = label;
mOptionalAttributes = OptionalAttributes.newInstance(outputText, KeyCode.NOT_SPECIFIED, mOptionalAttributes = OptionalAttributes.newInstance(outputText, KeyCode.NOT_SPECIFIED,
ICON_UNDEFINED, 0 /* visualInsetsLeft */, 0 /* visualInsetsRight */); KeyboardIconsSet.NAME_UNDEFINED, 0, 0);
mCode = code; mCode = code;
mEnabled = (code != KeyCode.NOT_SPECIFIED); mEnabled = (code != KeyCode.NOT_SPECIFIED);
mIconId = iconId; mIconName = iconName;
// Horizontal gap is divided equally to both sides of the key. // Horizontal gap is divided equally to both sides of the key.
mX = x + mHorizontalGap / 2; mX = x + mHorizontalGap / 2;
mY = y; mY = y;
@ -238,7 +236,7 @@ public class Key implements Comparable<Key> {
mLabel = key.mLabel; mLabel = key.mLabel;
mHintLabel = labelHint; mHintLabel = labelHint;
mLabelFlags = key.mLabelFlags; mLabelFlags = key.mLabelFlags;
mIconId = key.mIconId; mIconName = key.mIconName;
mWidth = key.mWidth; mWidth = key.mWidth;
mHeight = key.mHeight; mHeight = key.mHeight;
mHorizontalGap = key.mHorizontalGap; mHorizontalGap = key.mHorizontalGap;
@ -266,7 +264,7 @@ public class Key implements Comparable<Key> {
mLabel = outputText == null ? StringUtils.newSingleCodePointString(code) : outputText; mLabel = outputText == null ? StringUtils.newSingleCodePointString(code) : outputText;
mHintLabel = labelHint; mHintLabel = labelHint;
mLabelFlags = key.mLabelFlags; mLabelFlags = key.mLabelFlags;
mIconId = key.mIconId; mIconName = key.mIconName;
mWidth = key.mWidth; mWidth = key.mWidth;
mHeight = key.mHeight; mHeight = key.mHeight;
mHorizontalGap = key.mHorizontalGap; mHorizontalGap = key.mHorizontalGap;
@ -279,7 +277,8 @@ public class Key implements Comparable<Key> {
mBackgroundType = backgroundType; mBackgroundType = backgroundType;
mActionFlags = key.mActionFlags; mActionFlags = key.mActionFlags;
mKeyVisualAttributes = key.mKeyVisualAttributes; mKeyVisualAttributes = key.mKeyVisualAttributes;
mOptionalAttributes = outputText == null ? null : Key.OptionalAttributes.newInstance(outputText, KeyCode.NOT_SPECIFIED, ICON_UNDEFINED, 0, 0); mOptionalAttributes = outputText == null ? null
: Key.OptionalAttributes.newInstance(outputText, KeyCode.NOT_SPECIFIED, KeyboardIconsSet.NAME_UNDEFINED, 0, 0);
mHashCode = key.mHashCode; mHashCode = key.mHashCode;
// Key state. // Key state.
mPressed = key.mPressed; mPressed = key.mPressed;
@ -293,7 +292,7 @@ public class Key implements Comparable<Key> {
mLabel = keyParams.mLabel; mLabel = keyParams.mLabel;
mHintLabel = keyParams.mHintLabel; mHintLabel = keyParams.mHintLabel;
mLabelFlags = keyParams.mLabelFlags; mLabelFlags = keyParams.mLabelFlags;
mIconId = keyParams.mIconId; mIconName = keyParams.mIconName;
mPopupKeys = keyParams.mPopupKeys; mPopupKeys = keyParams.mPopupKeys;
mPopupKeysColumnAndFlags = keyParams.mPopupKeysColumnAndFlags; mPopupKeysColumnAndFlags = keyParams.mPopupKeysColumnAndFlags;
mBackgroundType = keyParams.mBackgroundType; mBackgroundType = keyParams.mBackgroundType;
@ -328,7 +327,7 @@ public class Key implements Comparable<Key> {
mLabel = key.mLabel; mLabel = key.mLabel;
mHintLabel = key.mHintLabel; mHintLabel = key.mHintLabel;
mLabelFlags = key.mLabelFlags; mLabelFlags = key.mLabelFlags;
mIconId = key.mIconId; mIconName = key.mIconName;
mWidth = key.mWidth; mWidth = key.mWidth;
mHeight = key.mHeight; mHeight = key.mHeight;
mHorizontalGap = key.mHorizontalGap; mHorizontalGap = key.mHorizontalGap;
@ -378,7 +377,7 @@ public class Key implements Comparable<Key> {
key.mCode, key.mCode,
key.mLabel, key.mLabel,
key.mHintLabel, key.mHintLabel,
key.mIconId, key.mIconName,
key.mBackgroundType, key.mBackgroundType,
Arrays.hashCode(key.mPopupKeys), Arrays.hashCode(key.mPopupKeys),
key.getOutputText(), key.getOutputText(),
@ -405,7 +404,7 @@ public class Key implements Comparable<Key> {
&& o.mCode == mCode && o.mCode == mCode
&& TextUtils.equals(o.mLabel, mLabel) && TextUtils.equals(o.mLabel, mLabel)
&& TextUtils.equals(o.mHintLabel, mHintLabel) && TextUtils.equals(o.mHintLabel, mHintLabel)
&& o.mIconId == mIconId && o.mIconName == mIconName
&& o.mBackgroundType == mBackgroundType && o.mBackgroundType == mBackgroundType
&& Arrays.equals(o.mPopupKeys, mPopupKeys) && Arrays.equals(o.mPopupKeys, mPopupKeys)
&& TextUtils.equals(o.getOutputText(), getOutputText()) && TextUtils.equals(o.getOutputText(), getOutputText())
@ -444,9 +443,9 @@ public class Key implements Comparable<Key> {
} }
public String toLongString() { public String toLongString() {
final int iconId = getIconId(); final String iconName = getIconName();
final String topVisual = (iconId == KeyboardIconsSet.ICON_UNDEFINED) final String topVisual = (iconName.equals(KeyboardIconsSet.NAME_UNDEFINED))
? KeyboardIconsSet.PREFIX_ICON + KeyboardIconsSet.getIconName(iconId) : getLabel(); ? KeyboardIconsSet.PREFIX_ICON + iconName : getLabel();
final String hintLabel = getHintLabel(); final String hintLabel = getHintLabel();
final String visual = (hintLabel == null) ? topVisual : topVisual + "^" + hintLabel; final String visual = (hintLabel == null) ? topVisual : topVisual + "^" + hintLabel;
return toString() + " " + visual + "/" + backgroundName(mBackgroundType); return toString() + " " + visual + "/" + backgroundName(mBackgroundType);
@ -702,16 +701,15 @@ public class Key implements Comparable<Key> {
return (attrs != null) ? attrs.mAltCode : KeyCode.NOT_SPECIFIED; return (attrs != null) ? attrs.mAltCode : KeyCode.NOT_SPECIFIED;
} }
public int getIconId() { public String getIconName() {
return mIconId; return mIconName;
} }
@Nullable @Nullable
public Drawable getIcon(final KeyboardIconsSet iconSet, final int alpha) { public Drawable getIcon(final KeyboardIconsSet iconSet, final int alpha) {
final OptionalAttributes attrs = mOptionalAttributes; final OptionalAttributes attrs = mOptionalAttributes;
final int disabledIconId = (attrs != null) ? attrs.mDisabledIconId : ICON_UNDEFINED; final String iconName = mEnabled ? getIconName() : ((attrs != null) ? attrs.mDisabledIconName : KeyboardIconsSet.NAME_UNDEFINED);
final int iconId = mEnabled ? getIconId() : disabledIconId; final Drawable icon = iconSet.getIconDrawable(iconName);
final Drawable icon = iconSet.getIconDrawable(iconId);
if (icon != null) { if (icon != null) {
icon.setAlpha(alpha); icon.setAlpha(alpha);
} }
@ -720,7 +718,7 @@ public class Key implements Comparable<Key> {
@Nullable @Nullable
public Drawable getPreviewIcon(final KeyboardIconsSet iconSet) { public Drawable getPreviewIcon(final KeyboardIconsSet iconSet) {
return iconSet.getIconDrawable(getIconId()); return iconSet.getIconDrawable(getIconName());
} }
/** /**
@ -902,7 +900,7 @@ public class Key implements Comparable<Key> {
public final Drawable selectBackgroundDrawable(@NonNull final Drawable keyBackground, public final Drawable selectBackgroundDrawable(@NonNull final Drawable keyBackground,
@NonNull final Drawable functionalKeyBackground, @NonNull final Drawable functionalKeyBackground,
@NonNull final Drawable spacebarBackground, @NonNull final Drawable spacebarBackground,
@NonNull final Drawable actionKeyBackground) { @NonNull final Drawable actionKeyBackground) {
final Drawable background; final Drawable background;
if (isAccentColored()) { if (isAccentColored()) {
background = actionKeyBackground; background = actionKeyBackground;
@ -920,7 +918,7 @@ public class Key implements Comparable<Key> {
public final boolean isAccentColored() { public final boolean isAccentColored() {
if (hasActionKeyBackground()) return true; if (hasActionKeyBackground()) return true;
final String iconName = KeyboardIconsSet.getIconName(getIconId()); final String iconName = getIconName();
return iconName.equals(KeyboardIconsSet.NAME_NEXT_KEY) return iconName.equals(KeyboardIconsSet.NAME_NEXT_KEY)
|| iconName.equals(KeyboardIconsSet.NAME_PREVIOUS_KEY) || iconName.equals(KeyboardIconsSet.NAME_PREVIOUS_KEY)
|| iconName.equals(KeyboardIconsSet.NAME_CLIPBOARD_ACTION_KEY) || iconName.equals(KeyboardIconsSet.NAME_CLIPBOARD_ACTION_KEY)
@ -943,8 +941,8 @@ public class Key implements Comparable<Key> {
*/ */
protected Spacer(final KeyboardParams params, final int x, final int y, final int width, protected Spacer(final KeyboardParams params, final int x, final int y, final int width,
final int height) { final int height) {
super(null /* label */, ICON_UNDEFINED, KeyCode.NOT_SPECIFIED, null /* outputText */, super(null, KeyboardIconsSet.NAME_UNDEFINED, KeyCode.NOT_SPECIFIED, null,
null /* hintLabel */, 0 /* labelFlags */, BACKGROUND_TYPE_EMPTY, x, y, width, null, 0, BACKGROUND_TYPE_EMPTY, x, y, width,
height, params.mHorizontalGap, params.mVerticalGap); height, params.mHorizontalGap, params.mVerticalGap);
} }
} }
@ -968,7 +966,7 @@ public class Key implements Comparable<Key> {
@Nullable public String mLabel; @Nullable public String mLabel;
@Nullable public final String mHintLabel; @Nullable public final String mHintLabel;
public final int mLabelFlags; public final int mLabelFlags;
public final int mIconId; @NonNull public final String mIconName;
@Nullable public PopupKeySpec[] mPopupKeys; @Nullable public PopupKeySpec[] mPopupKeys;
public final int mPopupKeysColumnAndFlags; public final int mPopupKeysColumnAndFlags;
public int mBackgroundType; public int mBackgroundType;
@ -1062,7 +1060,7 @@ public class Key implements Comparable<Key> {
mLabelFlags = labelFlags; mLabelFlags = labelFlags;
mWidth = width; mWidth = width;
mHeight = params.mDefaultRowHeight; mHeight = params.mDefaultRowHeight;
mIconId = KeySpecParser.getIconId(keySpec); mIconName = KeySpecParser.getIconName(keySpec);
final boolean needsToUpcase = needsToUpcase(mLabelFlags, params.mId.mElementId); final boolean needsToUpcase = needsToUpcase(mLabelFlags, params.mId.mElementId);
final Locale localeForUpcasing = params.mId.getLocale(); final Locale localeForUpcasing = params.mId.getLocale();
@ -1167,7 +1165,7 @@ public class Key implements Comparable<Key> {
: altCodeInAttr; : altCodeInAttr;
mOptionalAttributes = OptionalAttributes.newInstance(outputText, altCode, mOptionalAttributes = OptionalAttributes.newInstance(outputText, altCode,
// disabled icon only ever for old version of shortcut key, visual insets can be replaced with spacer // disabled icon only ever for old version of shortcut key, visual insets can be replaced with spacer
KeyboardIconsSet.ICON_UNDEFINED, 0, 0); KeyboardIconsSet.NAME_UNDEFINED, 0, 0);
// KeyVisualAttributes for a key essentially are what the theme has, but on a per-key base // KeyVisualAttributes for a key essentially are what the theme has, but on a per-key base
// could be used e.g. for having a color gradient on key color // could be used e.g. for having a color gradient on key color
mKeyVisualAttributes = null; mKeyVisualAttributes = null;
@ -1207,11 +1205,11 @@ public class Key implements Comparable<Key> {
mLabel = label; mLabel = label;
mOptionalAttributes = code == KeyCode.MULTIPLE_CODE_POINTS mOptionalAttributes = code == KeyCode.MULTIPLE_CODE_POINTS
? OptionalAttributes.newInstance(label, KeyCode.NOT_SPECIFIED, ICON_UNDEFINED, 0, 0) ? OptionalAttributes.newInstance(label, KeyCode.NOT_SPECIFIED, KeyboardIconsSet.NAME_UNDEFINED, 0, 0)
: null; : null;
mCode = code; mCode = code;
mEnabled = (code != KeyCode.NOT_SPECIFIED); mEnabled = (code != KeyCode.NOT_SPECIFIED);
mIconId = KeyboardIconsSet.ICON_UNDEFINED; mIconName = KeyboardIconsSet.NAME_UNDEFINED;
mKeyVisualAttributes = null; mKeyVisualAttributes = null;
} }
@ -1225,7 +1223,7 @@ public class Key implements Comparable<Key> {
mHintLabel = null; mHintLabel = null;
mKeyVisualAttributes = null; mKeyVisualAttributes = null;
mOptionalAttributes = null; mOptionalAttributes = null;
mIconId = KeyboardIconsSet.ICON_UNDEFINED; mIconName = KeyboardIconsSet.NAME_UNDEFINED;
mBackgroundType = BACKGROUND_TYPE_NORMAL; mBackgroundType = BACKGROUND_TYPE_NORMAL;
mActionFlags = ACTION_FLAGS_NO_KEY_PREVIEW; mActionFlags = ACTION_FLAGS_NO_KEY_PREVIEW;
mPopupKeys = null; mPopupKeys = null;
@ -1247,7 +1245,7 @@ public class Key implements Comparable<Key> {
mLabel = keyParams.mLabel; mLabel = keyParams.mLabel;
mHintLabel = keyParams.mHintLabel; mHintLabel = keyParams.mHintLabel;
mLabelFlags = keyParams.mLabelFlags; mLabelFlags = keyParams.mLabelFlags;
mIconId = keyParams.mIconId; mIconName = keyParams.mIconName;
mAbsoluteWidth = keyParams.mAbsoluteWidth; mAbsoluteWidth = keyParams.mAbsoluteWidth;
mAbsoluteHeight = keyParams.mAbsoluteHeight; mAbsoluteHeight = keyParams.mAbsoluteHeight;
mPopupKeys = keyParams.mPopupKeys; mPopupKeys = keyParams.mPopupKeys;

View file

@ -39,6 +39,7 @@ import helium314.keyboard.latin.common.StringUtils;
import helium314.keyboard.latin.settings.Settings; import helium314.keyboard.latin.settings.Settings;
import helium314.keyboard.latin.suggestions.MoreSuggestions; import helium314.keyboard.latin.suggestions.MoreSuggestions;
import helium314.keyboard.latin.suggestions.PopupSuggestionsView; import helium314.keyboard.latin.suggestions.PopupSuggestionsView;
import helium314.keyboard.latin.utils.Log;
import helium314.keyboard.latin.utils.TypefaceUtils; import helium314.keyboard.latin.utils.TypefaceUtils;
import java.util.HashSet; import java.util.HashSet;

View file

@ -141,9 +141,9 @@ class ClipboardHistoryView @JvmOverloads constructor(
} }
} }
private fun setupDeleteKey(key: ImageButton, iconId: Int) { private fun setupDeleteKey(key: ImageButton, icon: Drawable?) {
key.apply { key.apply {
setImageResource(iconId) setImageDrawable(icon)
Settings.getInstance().current.mColors.setBackground(this, ColorType.FUNCTIONAL_KEY_BACKGROUND) Settings.getInstance().current.mColors.setBackground(this, ColorType.FUNCTIONAL_KEY_BACKGROUND)
Settings.getInstance().current.mColors.setColor(this, ColorType.KEY_ICON) Settings.getInstance().current.mColors.setColor(this, ColorType.KEY_ICON)
} }
@ -189,7 +189,7 @@ class ClipboardHistoryView @JvmOverloads constructor(
val params = KeyDrawParams() val params = KeyDrawParams()
params.updateParams(clipboardLayoutParams.actionBarContentHeight, keyVisualAttr) params.updateParams(clipboardLayoutParams.actionBarContentHeight, keyVisualAttr)
setupAlphabetKey(alphabetKey, switchToAlphaLabel, params) setupAlphabetKey(alphabetKey, switchToAlphaLabel, params)
setupDeleteKey(deleteKey, iconSet.getIconResourceId(KeyboardIconsSet.NAME_DELETE_KEY)) setupDeleteKey(deleteKey, iconSet.getIconDrawable(KeyboardIconsSet.NAME_DELETE_KEY))
setupClipKey(params) setupClipKey(params)
placeholderView.apply { placeholderView.apply {

View file

@ -360,10 +360,7 @@ public final class EmojiPalettesView extends LinearLayout
final KeyVisualAttributes keyVisualAttr, final KeyVisualAttributes keyVisualAttr,
final KeyboardIconsSet iconSet) { final KeyboardIconsSet iconSet) {
initialize(); initialize();
final int deleteIconResId = iconSet.getIconResourceId(KeyboardIconsSet.NAME_DELETE_KEY); mDeleteKey.setImageDrawable(iconSet.getIconDrawable(KeyboardIconsSet.NAME_DELETE_KEY));
if (deleteIconResId != 0) {
mDeleteKey.setImageResource(deleteIconResId);
}
mEmojiLayoutParams.setActionBarProperties(findViewById(R.id.action_bar)); mEmojiLayoutParams.setActionBarProperties(findViewById(R.id.action_bar));
final KeyDrawParams params = new KeyDrawParams(); final KeyDrawParams params = new KeyDrawParams();
params.updateParams(mEmojiLayoutParams.getActionBarHeight(), keyVisualAttr); params.updateParams(mEmojiLayoutParams.getActionBarHeight(), keyVisualAttr);

View file

@ -43,11 +43,9 @@ public class KeyPreviewView extends AppCompatTextView {
setGravity(Gravity.CENTER); setGravity(Gravity.CENTER);
} }
public void setPreviewVisual(final Key key, final KeyboardIconsSet iconsSet, public void setPreviewVisual(final Key key, final KeyboardIconsSet iconsSet, final KeyDrawParams drawParams) {
final KeyDrawParams drawParams) {
// What we show as preview should match what we show on a key top in onDraw(). // What we show as preview should match what we show on a key top in onDraw().
final int iconId = key.getIconId(); if (!key.getIconName().equals(KeyboardIconsSet.NAME_UNDEFINED)) {
if (iconId != KeyboardIconsSet.ICON_UNDEFINED) {
setCompoundDrawables(null, null, null, key.getPreviewIcon(iconsSet)); setCompoundDrawables(null, null, null, key.getPreviewIcon(iconsSet));
setText(null); setText(null);
return; return;

View file

@ -221,18 +221,17 @@ public final class KeySpecParser {
return defaultCode; return defaultCode;
} }
public static int getIconId(@Nullable final String keySpec) { @NonNull
public static String getIconName(@Nullable final String keySpec) {
if (keySpec == null) { if (keySpec == null) {
// TODO: Throw {@link KeySpecParserError} once Key.keyLabel attribute becomes mandatory. // TODO: Throw {@link KeySpecParserError} once Key.keyLabel attribute becomes mandatory.
return KeyboardIconsSet.ICON_UNDEFINED; return KeyboardIconsSet.NAME_UNDEFINED;
} }
if (!hasIcon(keySpec)) { if (!hasIcon(keySpec)) {
return KeyboardIconsSet.ICON_UNDEFINED; return KeyboardIconsSet.NAME_UNDEFINED;
} }
final int labelEnd = indexOfLabelEnd(keySpec); final int labelEnd = indexOfLabelEnd(keySpec);
final String iconName = getBeforeLabelEnd(keySpec, labelEnd) return getBeforeLabelEnd(keySpec, labelEnd).substring(KeyboardIconsSet.PREFIX_ICON.length()).intern();
.substring(KeyboardIconsSet.PREFIX_ICON.length());
return KeyboardIconsSet.getIconId(iconName);
} }
public static final class KeySpecParserError extends RuntimeException { public static final class KeySpecParserError extends RuntimeException {

View file

@ -1,196 +0,0 @@
/*
* Copyright (C) 2011 The Android Open Source Project
* modified
* SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
*/
package helium314.keyboard.keyboard.internal;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import helium314.keyboard.latin.utils.Log;
import android.util.SparseIntArray;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import helium314.keyboard.latin.R;
import helium314.keyboard.latin.utils.ToolbarKey;
import java.util.HashMap;
public final class KeyboardIconsSet {
private static final String TAG = KeyboardIconsSet.class.getSimpleName();
public static final String PREFIX_ICON = "!icon/";
public static final int ICON_UNDEFINED = 0;
private static final int ATTR_UNDEFINED = 0;
private static final String NAME_UNDEFINED = "undefined";
public static final String NAME_SHIFT_KEY = "shift_key";
public static final String NAME_SHIFT_KEY_SHIFTED = "shift_key_shifted";
public static final String NAME_DELETE_KEY = "delete_key";
public static final String NAME_SETTINGS_KEY = "settings_key";
public static final String NAME_SPACE_KEY = "space_key";
public static final String NAME_SPACE_KEY_FOR_NUMBER_LAYOUT = "space_key_for_number_layout";
public static final String NAME_ENTER_KEY = "enter_key";
public static final String NAME_GO_KEY = "go_key";
public static final String NAME_SEARCH_KEY = "search_key";
public static final String NAME_SEND_KEY = "send_key";
public static final String NAME_NEXT_KEY = "next_key";
public static final String NAME_DONE_KEY = "done_key";
public static final String NAME_PREVIOUS_KEY = "previous_key";
public static final String NAME_TAB_KEY = "tab_key";
public static final String NAME_SHORTCUT_KEY = "shortcut_key";
public static final String NAME_INCOGNITO_KEY = "incognito_key";
public static final String NAME_SHORTCUT_KEY_DISABLED = "shortcut_key_disabled";
public static final String NAME_LANGUAGE_SWITCH_KEY = "language_switch_key";
public static final String NAME_ZWNJ_KEY = "zwnj_key";
public static final String NAME_ZWJ_KEY = "zwj_key";
public static final String NAME_EMOJI_ACTION_KEY = "emoji_action_key";
public static final String NAME_EMOJI_NORMAL_KEY = "emoji_normal_key";
public static final String NAME_CLIPBOARD_ACTION_KEY = "clipboard_action_key";
public static final String NAME_CLIPBOARD_NORMAL_KEY = "clipboard_normal_key";
public static final String NAME_CLEAR_CLIPBOARD_KEY = "clear_clipboard_key";
public static final String NAME_CUT_KEY = "cut_key";
public static final String NAME_NUMPAD_KEY = "numpad_key";
public static final String NAME_START_ONEHANDED_KEY = "start_onehanded_mode_key";
public static final String NAME_STOP_ONEHANDED_KEY = "stop_onehanded_mode_key";
public static final String NAME_SWITCH_ONEHANDED_KEY = "switch_onehanded_key";
private static final SparseIntArray ATTR_ID_TO_ICON_ID = new SparseIntArray();
// Icon name to icon id map.
private static final HashMap<String, Integer> sNameToIdsMap = new HashMap<>();
private static final Object[] NAMES_AND_ATTR_IDS = {
NAME_UNDEFINED, ATTR_UNDEFINED,
NAME_SHIFT_KEY, R.styleable.Keyboard_iconShiftKey,
NAME_DELETE_KEY, R.styleable.Keyboard_iconDeleteKey,
NAME_SETTINGS_KEY, R.styleable.Keyboard_iconSettingsKey,
NAME_SPACE_KEY, R.styleable.Keyboard_iconSpaceKey,
NAME_ENTER_KEY, R.styleable.Keyboard_iconEnterKey,
NAME_GO_KEY, R.styleable.Keyboard_iconGoKey,
NAME_SEARCH_KEY, R.styleable.Keyboard_iconSearchKey,
NAME_SEND_KEY, R.styleable.Keyboard_iconSendKey,
NAME_NEXT_KEY, R.styleable.Keyboard_iconNextKey,
NAME_DONE_KEY, R.styleable.Keyboard_iconDoneKey,
NAME_PREVIOUS_KEY, R.styleable.Keyboard_iconPreviousKey,
NAME_TAB_KEY, R.styleable.Keyboard_iconTabKey,
NAME_SHORTCUT_KEY, R.styleable.Keyboard_iconShortcutKey,
NAME_INCOGNITO_KEY, R.styleable.Keyboard_iconIncognitoKey,
NAME_SPACE_KEY_FOR_NUMBER_LAYOUT, R.styleable.Keyboard_iconSpaceKeyForNumberLayout,
NAME_SHIFT_KEY_SHIFTED, R.styleable.Keyboard_iconShiftKeyShifted,
NAME_SHORTCUT_KEY_DISABLED, R.styleable.Keyboard_iconShortcutKeyDisabled,
NAME_LANGUAGE_SWITCH_KEY, R.styleable.Keyboard_iconLanguageSwitchKey,
NAME_ZWNJ_KEY, R.styleable.Keyboard_iconZwnjKey,
NAME_ZWJ_KEY, R.styleable.Keyboard_iconZwjKey,
NAME_EMOJI_ACTION_KEY, R.styleable.Keyboard_iconEmojiActionKey,
NAME_EMOJI_NORMAL_KEY, R.styleable.Keyboard_iconEmojiNormalKey,
NAME_CLIPBOARD_ACTION_KEY, R.styleable.Keyboard_iconClipboardActionKey,
NAME_CLIPBOARD_NORMAL_KEY, R.styleable.Keyboard_iconClipboardNormalKey,
NAME_CLEAR_CLIPBOARD_KEY, R.styleable.Keyboard_iconClearClipboardKey,
NAME_CUT_KEY, R.styleable.Keyboard_iconCutKey,
NAME_NUMPAD_KEY, R.styleable.Keyboard_iconNumpadKey,
NAME_START_ONEHANDED_KEY, R.styleable.Keyboard_iconStartOneHandedMode,
NAME_STOP_ONEHANDED_KEY, R.styleable.Keyboard_iconStopOneHandedMode,
NAME_SWITCH_ONEHANDED_KEY, R.styleable.Keyboard_iconSwitchOneHandedMode,
ToolbarKey.VOICE.name(), R.styleable.Keyboard_iconShortcutKey,
ToolbarKey.SETTINGS.name(), R.styleable.Keyboard_iconSettingsKey,
ToolbarKey.CLIPBOARD.name(), R.styleable.Keyboard_iconClipboardNormalKey,
ToolbarKey.SELECT_ALL.name(), R.styleable.Keyboard_iconSelectAll,
ToolbarKey.COPY.name(), R.styleable.Keyboard_iconCopyKey,
ToolbarKey.CUT.name(), R.styleable.Keyboard_iconCutKey,
ToolbarKey.ONE_HANDED.name(), R.styleable.Keyboard_iconStartOneHandedMode,
ToolbarKey.LEFT.name(), R.styleable.Keyboard_iconArrowLeft,
ToolbarKey.RIGHT.name(), R.styleable.Keyboard_iconArrowRight,
ToolbarKey.UP.name(), R.styleable.Keyboard_iconArrowUp,
ToolbarKey.DOWN.name(), R.styleable.Keyboard_iconArrowDown,
ToolbarKey.UNDO.name(), R.styleable.Keyboard_iconUndo,
ToolbarKey.REDO.name(), R.styleable.Keyboard_iconRedo,
ToolbarKey.INCOGNITO.name(), R.styleable.Keyboard_iconIncognitoKey,
ToolbarKey.AUTOCORRECT.name(), R.styleable.Keyboard_iconAutoCorrect,
ToolbarKey.CLEAR_CLIPBOARD.name(),R.styleable.Keyboard_iconClearClipboardKey,
ToolbarKey.FULL_LEFT.name(), R.styleable.Keyboard_iconFullLeft,
ToolbarKey.FULL_RIGHT.name(), R.styleable.Keyboard_iconFullRight,
ToolbarKey.SELECT_WORD.name(), R.styleable.Keyboard_iconSelectWord,
ToolbarKey.CLOSE_HISTORY.name(), R.styleable.Keyboard_iconClose,
};
private static final int NUM_ICONS = NAMES_AND_ATTR_IDS.length / 2;
private static final String[] ICON_NAMES = new String[NUM_ICONS];
private final Drawable[] mIcons = new Drawable[NUM_ICONS];
private final int[] mIconResourceIds = new int[NUM_ICONS];
static {
int iconId = ICON_UNDEFINED;
for (int i = 0; i < NAMES_AND_ATTR_IDS.length; i += 2) {
final String name = (String)NAMES_AND_ATTR_IDS[i];
final Integer attrId = (Integer)NAMES_AND_ATTR_IDS[i + 1];
if (attrId != ATTR_UNDEFINED) {
ATTR_ID_TO_ICON_ID.put(attrId, iconId);
}
sNameToIdsMap.put(name, iconId);
ICON_NAMES[iconId] = name;
iconId++;
}
}
public void loadIcons(final TypedArray keyboardAttrs) {
final int size = ATTR_ID_TO_ICON_ID.size();
for (int index = 0; index < size; index++) {
final int attrId = ATTR_ID_TO_ICON_ID.keyAt(index);
try {
final Drawable icon = keyboardAttrs.getDrawable(attrId);
setDefaultBounds(icon);
final Integer iconId = ATTR_ID_TO_ICON_ID.get(attrId);
mIcons[iconId] = icon;
mIconResourceIds[iconId] = keyboardAttrs.getResourceId(attrId, 0);
} catch (Resources.NotFoundException e) {
Log.w(TAG, "Drawable resource for icon #"
+ keyboardAttrs.getResources().getResourceEntryName(attrId)
+ " not found");
}
}
}
private static boolean isValidIconId(final int iconId) {
return iconId >= 0 && iconId < ICON_NAMES.length;
}
@NonNull
public static String getIconName(final int iconId) {
return isValidIconId(iconId) ? ICON_NAMES[iconId] : "unknown<" + iconId + ">";
}
public static int getIconId(final String name) {
Integer iconId = sNameToIdsMap.get(name);
if (iconId != null) {
return iconId;
}
throw new RuntimeException("unknown icon name: " + name);
}
public int getIconResourceId(final String name) {
final int iconId = getIconId(name);
if (isValidIconId(iconId)) {
return mIconResourceIds[iconId];
}
throw new RuntimeException("unknown icon name: " + name);
}
@Nullable
public Drawable getIconDrawable(final int iconId) {
if (isValidIconId(iconId)) {
return mIcons[iconId];
}
throw new RuntimeException("unknown icon id: " + getIconName(iconId));
}
private static void setDefaultBounds(final Drawable icon) {
if (icon != null) {
icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
}
}
}

View file

@ -0,0 +1,97 @@
package helium314.keyboard.keyboard.internal
import android.content.res.Resources
import android.content.res.TypedArray
import android.graphics.drawable.Drawable
import helium314.keyboard.latin.R
import helium314.keyboard.latin.utils.Log
import helium314.keyboard.latin.utils.ToolbarKey
import helium314.keyboard.latin.utils.getStyleableIconId
class KeyboardIconsSet {
private val iconsByName = HashMap<String, Drawable>(styleableIdByName.size)
fun loadIcons(keyboardAttrs: TypedArray) {
styleableIdByName.forEach { (name, id) ->
try {
val icon = keyboardAttrs.getDrawable(id) ?: return@forEach
icon.setBounds(0, 0, icon.intrinsicWidth, icon.intrinsicHeight)
iconsByName[name] = icon
} catch (e: Resources.NotFoundException) {
Log.w(TAG, "Drawable resource for icon #${keyboardAttrs.resources.getResourceEntryName(id)} not found")
}
}
}
fun getIconDrawable(name: String) = iconsByName[name]
companion object {
private val TAG = KeyboardIconsSet::class.simpleName
const val PREFIX_ICON = "!icon/"
const val NAME_UNDEFINED = "undefined"
const val NAME_SHIFT_KEY = "shift_key"
const val NAME_SHIFT_KEY_SHIFTED = "shift_key_shifted"
const val NAME_DELETE_KEY = "delete_key"
const val NAME_SETTINGS_KEY = "settings_key"
const val NAME_SPACE_KEY = "space_key"
const val NAME_SPACE_KEY_FOR_NUMBER_LAYOUT = "space_key_for_number_layout"
const val NAME_ENTER_KEY = "enter_key"
const val NAME_GO_KEY = "go_key"
const val NAME_SEARCH_KEY = "search_key"
const val NAME_SEND_KEY = "send_key"
const val NAME_NEXT_KEY = "next_key"
const val NAME_DONE_KEY = "done_key"
const val NAME_PREVIOUS_KEY = "previous_key"
const val NAME_TAB_KEY = "tab_key"
const val NAME_SHORTCUT_KEY = "shortcut_key"
const val NAME_INCOGNITO_KEY = "incognito_key"
const val NAME_SHORTCUT_KEY_DISABLED = "shortcut_key_disabled"
const val NAME_LANGUAGE_SWITCH_KEY = "language_switch_key"
const val NAME_ZWNJ_KEY = "zwnj_key"
const val NAME_ZWJ_KEY = "zwj_key"
const val NAME_EMOJI_ACTION_KEY = "emoji_action_key"
const val NAME_EMOJI_NORMAL_KEY = "emoji_normal_key"
const val NAME_CLIPBOARD_ACTION_KEY = "clipboard_action_key"
const val NAME_CLIPBOARD_NORMAL_KEY = "clipboard_normal_key"
const val NAME_CLEAR_CLIPBOARD_KEY = "clear_clipboard_key"
const val NAME_CUT_KEY = "cut_key"
const val NAME_NUMPAD_KEY = "numpad_key"
const val NAME_START_ONEHANDED_KEY = "start_onehanded_mode_key"
const val NAME_STOP_ONEHANDED_KEY = "stop_onehanded_mode_key"
const val NAME_SWITCH_ONEHANDED_KEY = "switch_onehanded_key"
private val styleableIdByName = hashMapOf(
NAME_SHIFT_KEY to R.styleable.Keyboard_iconShiftKey,
NAME_DELETE_KEY to R.styleable.Keyboard_iconDeleteKey,
NAME_SETTINGS_KEY to R.styleable.Keyboard_iconSettingsKey,
NAME_SPACE_KEY to R.styleable.Keyboard_iconSpaceKey,
NAME_ENTER_KEY to R.styleable.Keyboard_iconEnterKey,
NAME_GO_KEY to R.styleable.Keyboard_iconGoKey,
NAME_SEARCH_KEY to R.styleable.Keyboard_iconSearchKey,
NAME_SEND_KEY to R.styleable.Keyboard_iconSendKey,
NAME_NEXT_KEY to R.styleable.Keyboard_iconNextKey,
NAME_DONE_KEY to R.styleable.Keyboard_iconDoneKey,
NAME_PREVIOUS_KEY to R.styleable.Keyboard_iconPreviousKey,
NAME_TAB_KEY to R.styleable.Keyboard_iconTabKey,
NAME_SHORTCUT_KEY to R.styleable.Keyboard_iconShortcutKey,
NAME_INCOGNITO_KEY to R.styleable.Keyboard_iconIncognitoKey,
NAME_SPACE_KEY_FOR_NUMBER_LAYOUT to R.styleable.Keyboard_iconSpaceKeyForNumberLayout,
NAME_SHIFT_KEY_SHIFTED to R.styleable.Keyboard_iconShiftKeyShifted,
NAME_SHORTCUT_KEY_DISABLED to R.styleable.Keyboard_iconShortcutKeyDisabled,
NAME_LANGUAGE_SWITCH_KEY to R.styleable.Keyboard_iconLanguageSwitchKey,
NAME_ZWNJ_KEY to R.styleable.Keyboard_iconZwnjKey,
NAME_ZWJ_KEY to R.styleable.Keyboard_iconZwjKey,
NAME_EMOJI_ACTION_KEY to R.styleable.Keyboard_iconEmojiActionKey,
NAME_EMOJI_NORMAL_KEY to R.styleable.Keyboard_iconEmojiNormalKey,
NAME_CLIPBOARD_ACTION_KEY to R.styleable.Keyboard_iconClipboardActionKey,
NAME_CLIPBOARD_NORMAL_KEY to R.styleable.Keyboard_iconClipboardNormalKey,
NAME_CLEAR_CLIPBOARD_KEY to R.styleable.Keyboard_iconClearClipboardKey,
NAME_CUT_KEY to R.styleable.Keyboard_iconCutKey,
NAME_NUMPAD_KEY to R.styleable.Keyboard_iconNumpadKey,
NAME_START_ONEHANDED_KEY to R.styleable.Keyboard_iconStartOneHandedMode,
NAME_STOP_ONEHANDED_KEY to R.styleable.Keyboard_iconStopOneHandedMode,
NAME_SWITCH_ONEHANDED_KEY to R.styleable.Keyboard_iconSwitchOneHandedMode,
).apply { ToolbarKey.entries.forEach { put(it.name, getStyleableIconId(it)) } }
}
}

View file

@ -40,7 +40,8 @@ public final class PopupKeySpec {
public final String mLabel; public final String mLabel;
@Nullable @Nullable
public final String mOutputText; public final String mOutputText;
public final int mIconId; @NonNull
public final String mIconName;
public PopupKeySpec(@NonNull final String popupKeySpec, boolean needsToUpperCase, public PopupKeySpec(@NonNull final String popupKeySpec, boolean needsToUpperCase,
@NonNull final Locale locale) { @NonNull final Locale locale) {
@ -63,13 +64,13 @@ public final class PopupKeySpec {
mOutputText = needsToUpperCase mOutputText = needsToUpperCase
? StringUtils.toTitleCaseOfKeyLabel(outputText, locale) : outputText; ? StringUtils.toTitleCaseOfKeyLabel(outputText, locale) : outputText;
} }
mIconId = KeySpecParser.getIconId(popupKeySpec); mIconName = KeySpecParser.getIconName(popupKeySpec);
} }
@NonNull @NonNull
public Key buildKey(final int x, final int y, final int labelFlags, public Key buildKey(final int x, final int y, final int labelFlags,
@NonNull final KeyboardParams params) { @NonNull final KeyboardParams params) {
return new Key(mLabel, mIconId, mCode, mOutputText, null /* hintLabel */, labelFlags, return new Key(mLabel, mIconName, mCode, mOutputText, null /* hintLabel */, labelFlags,
Key.BACKGROUND_TYPE_NORMAL, x, y, params.mDefaultAbsoluteKeyWidth, params.mDefaultAbsoluteRowHeight, Key.BACKGROUND_TYPE_NORMAL, x, y, params.mDefaultAbsoluteKeyWidth, params.mDefaultAbsoluteRowHeight,
params.mHorizontalGap, params.mVerticalGap); params.mHorizontalGap, params.mVerticalGap);
} }
@ -77,7 +78,7 @@ public final class PopupKeySpec {
@Override @Override
public int hashCode() { public int hashCode() {
int hashCode = 31 + mCode; int hashCode = 31 + mCode;
hashCode = hashCode * 31 + mIconId; hashCode = hashCode * 31 + mIconName.hashCode();
final String label = mLabel; final String label = mLabel;
hashCode = hashCode * 31 + (label == null ? 0 : label.hashCode()); hashCode = hashCode * 31 + (label == null ? 0 : label.hashCode());
final String outputText = mOutputText; final String outputText = mOutputText;
@ -93,7 +94,7 @@ public final class PopupKeySpec {
if (o instanceof PopupKeySpec) { if (o instanceof PopupKeySpec) {
final PopupKeySpec other = (PopupKeySpec)o; final PopupKeySpec other = (PopupKeySpec)o;
return mCode == other.mCode return mCode == other.mCode
&& mIconId == other.mIconId && mIconName.equals(other.mIconName)
&& TextUtils.equals(mLabel, other.mLabel) && TextUtils.equals(mLabel, other.mLabel)
&& TextUtils.equals(mOutputText, other.mOutputText); && TextUtils.equals(mOutputText, other.mOutputText);
} }
@ -102,8 +103,8 @@ public final class PopupKeySpec {
@Override @Override
public String toString() { public String toString() {
final String label = (mIconId == KeyboardIconsSet.ICON_UNDEFINED ? mLabel final String label = (mIconName.equals(KeyboardIconsSet.NAME_UNDEFINED) ? mLabel
: KeyboardIconsSet.PREFIX_ICON + KeyboardIconsSet.getIconName(mIconId)); : KeyboardIconsSet.PREFIX_ICON + mIconName);
final String output = (mCode == KeyCode.MULTIPLE_CODE_POINTS ? mOutputText final String output = (mCode == KeyCode.MULTIPLE_CODE_POINTS ? mOutputText
: Constants.printableCode(mCode)); : Constants.printableCode(mCode));
if (StringUtils.codePointCount(label) == 1 && label.codePointAt(0) == mCode) { if (StringUtils.codePointCount(label) == 1 && label.codePointAt(0) == mCode) {

View file

@ -467,7 +467,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
} }
private fun String.replaceIconWithLabelIfNoDrawable(): String { private fun String.replaceIconWithLabelIfNoDrawable(): String {
if (params.mIconsSet.getIconDrawable(KeyboardIconsSet.getIconId(this)) != null) return this if (params.mIconsSet.getIconDrawable(this) != null) return this
if (params.mId.mWidth == AndroidSpellCheckerService.SPELLCHECKER_DUMMY_KEYBOARD_WIDTH if (params.mId.mWidth == AndroidSpellCheckerService.SPELLCHECKER_DUMMY_KEYBOARD_WIDTH
&& params.mId.mHeight == AndroidSpellCheckerService.SPELLCHECKER_DUMMY_KEYBOARD_HEIGHT && params.mId.mHeight == AndroidSpellCheckerService.SPELLCHECKER_DUMMY_KEYBOARD_HEIGHT
&& !params.mId.mSubtype.hasExtraValue(Constants.Subtype.ExtraValue.EMOJI_CAPABLE) && !params.mId.mSubtype.hasExtraValue(Constants.Subtype.ExtraValue.EMOJI_CAPABLE)

View file

@ -230,8 +230,8 @@ public final class MoreSuggestions extends Keyboard {
public MoreSuggestionKey(final String word, final String info, final int index, public MoreSuggestionKey(final String word, final String info, final int index,
final MoreSuggestionsParam params) { final MoreSuggestionsParam params) {
super(word /* label */, KeyboardIconsSet.ICON_UNDEFINED, KeyCode.MULTIPLE_CODE_POINTS, super(word, KeyboardIconsSet.NAME_UNDEFINED, KeyCode.MULTIPLE_CODE_POINTS,
word /* outputText */, info, 0 /* labelFlags */, Key.BACKGROUND_TYPE_NORMAL, word, info, 0, Key.BACKGROUND_TYPE_NORMAL,
params.getX(index), params.getY(index), params.getWidth(index), params.getX(index), params.getY(index), params.getWidth(index),
params.mDefaultAbsoluteRowHeight, params.mHorizontalGap, params.mVerticalGap); params.mDefaultAbsoluteRowHeight, params.mHorizontalGap, params.mVerticalGap);
mSuggestedWordIndex = index; mSuggestedWordIndex = index;

View file

@ -10,7 +10,6 @@ import android.widget.ImageView
import androidx.appcompat.view.ContextThemeWrapper import androidx.appcompat.view.ContextThemeWrapper
import androidx.core.content.edit import androidx.core.content.edit
import helium314.keyboard.keyboard.KeyboardTheme import helium314.keyboard.keyboard.KeyboardTheme
import helium314.keyboard.keyboard.internal.KeyboardIconsSet
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
import helium314.keyboard.latin.R import helium314.keyboard.latin.R
import helium314.keyboard.latin.settings.Settings import helium314.keyboard.latin.settings.Settings
@ -74,8 +73,7 @@ fun getCodeForToolbarKeyLongClick(key: ToolbarKey) = when (key) {
else -> KeyCode.UNSPECIFIED else -> KeyCode.UNSPECIFIED
} }
// todo: get the icons from KeyboardIconsSet (but currently it's loaded too late) fun getStyleableIconId(key: ToolbarKey) = when (key) {
private fun getStyleableIconId(key: ToolbarKey) = when (key) {
VOICE -> R.styleable.Keyboard_iconShortcutKey VOICE -> R.styleable.Keyboard_iconShortcutKey
SETTINGS -> R.styleable.Keyboard_iconSettingsKey SETTINGS -> R.styleable.Keyboard_iconSettingsKey
CLIPBOARD -> R.styleable.Keyboard_iconClipboardNormalKey CLIPBOARD -> R.styleable.Keyboard_iconClipboardNormalKey