From 3862d1e9b28026e5f51124c7f2a6b58d61a7248a Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sun, 12 May 2024 18:08:15 +0200 Subject: [PATCH] identify keyboard icons by name only re-work KeyboardIconsSet also fixes a recent regression where some icons are not displayed --- .../java/helium314/keyboard/keyboard/Key.java | 76 ++++--- .../keyboard/keyboard/KeyboardView.java | 1 + .../clipboard/ClipboardHistoryView.kt | 6 +- .../keyboard/emoji/EmojiPalettesView.java | 5 +- .../keyboard/internal/KeyPreviewView.java | 6 +- .../keyboard/internal/KeySpecParser.java | 11 +- .../keyboard/internal/KeyboardIconsSet.java | 196 ------------------ .../keyboard/internal/KeyboardIconsSet.kt | 97 +++++++++ .../keyboard/internal/PopupKeySpec.java | 15 +- .../keyboard_parser/KeyboardParser.kt | 2 +- .../latin/suggestions/MoreSuggestions.java | 4 +- .../keyboard/latin/utils/ToolbarUtils.kt | 4 +- 12 files changed, 158 insertions(+), 265 deletions(-) delete mode 100644 app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardIconsSet.java create mode 100644 app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardIconsSet.kt diff --git a/app/src/main/java/helium314/keyboard/keyboard/Key.java b/app/src/main/java/helium314/keyboard/keyboard/Key.java index 078b3e2c5..231dd05ad 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/Key.java +++ b/app/src/main/java/helium314/keyboard/keyboard/Key.java @@ -26,8 +26,6 @@ import helium314.keyboard.latin.utils.PopupKeysUtilsKt; import java.util.Arrays; import java.util.Locale; -import static helium314.keyboard.keyboard.internal.KeyboardIconsSet.ICON_UNDEFINED; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -80,7 +78,7 @@ public class Key implements Comparable { public static final int LABEL_FLAGS_DISABLE_ADDITIONAL_POPUP_KEYS = 0x80000000; /** 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 */ private final int mWidth; @@ -156,29 +154,29 @@ public class Key implements Comparable { public final String mOutputText; public final int mAltCode; /** Icon for disabled state */ - public final int mDisabledIconId; + public final String mDisabledIconName; /** The visual insets */ public final int mVisualInsetsLeft; public final int mVisualInsetsRight; 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; mAltCode = altCode; - mDisabledIconId = disabledIconId; + mDisabledIconName = disabledIconName; mVisualInsetsLeft = visualInsetsLeft; mVisualInsetsRight = visualInsetsRight; } @Nullable 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 - && disabledIconId == ICON_UNDEFINED && visualInsetsLeft == 0 + && disabledIconName.equals(KeyboardIconsSet.NAME_UNDEFINED) && visualInsetsLeft == 0 && visualInsetsRight == 0) { return null; } - return new OptionalAttributes(outputText, altCode, disabledIconId, visualInsetsLeft, + return new OptionalAttributes(outputText, altCode, disabledIconName, visualInsetsLeft, visualInsetsRight); } } @@ -193,7 +191,7 @@ public class Key implements Comparable { /** * Constructor for a key on PopupKeyKeyboard and on MoreSuggestions. */ - 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, final int labelFlags, final int backgroundType, final int x, final int y, final int width, final int height, final int horizontalGap, final int verticalGap) { @@ -210,10 +208,10 @@ public class Key implements Comparable { mPopupKeysColumnAndFlags = 0; mLabel = label; mOptionalAttributes = OptionalAttributes.newInstance(outputText, KeyCode.NOT_SPECIFIED, - ICON_UNDEFINED, 0 /* visualInsetsLeft */, 0 /* visualInsetsRight */); + KeyboardIconsSet.NAME_UNDEFINED, 0, 0); mCode = code; mEnabled = (code != KeyCode.NOT_SPECIFIED); - mIconId = iconId; + mIconName = iconName; // Horizontal gap is divided equally to both sides of the key. mX = x + mHorizontalGap / 2; mY = y; @@ -238,7 +236,7 @@ public class Key implements Comparable { mLabel = key.mLabel; mHintLabel = labelHint; mLabelFlags = key.mLabelFlags; - mIconId = key.mIconId; + mIconName = key.mIconName; mWidth = key.mWidth; mHeight = key.mHeight; mHorizontalGap = key.mHorizontalGap; @@ -266,7 +264,7 @@ public class Key implements Comparable { mLabel = outputText == null ? StringUtils.newSingleCodePointString(code) : outputText; mHintLabel = labelHint; mLabelFlags = key.mLabelFlags; - mIconId = key.mIconId; + mIconName = key.mIconName; mWidth = key.mWidth; mHeight = key.mHeight; mHorizontalGap = key.mHorizontalGap; @@ -279,7 +277,8 @@ public class Key implements Comparable { mBackgroundType = backgroundType; mActionFlags = key.mActionFlags; 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; // Key state. mPressed = key.mPressed; @@ -293,7 +292,7 @@ public class Key implements Comparable { mLabel = keyParams.mLabel; mHintLabel = keyParams.mHintLabel; mLabelFlags = keyParams.mLabelFlags; - mIconId = keyParams.mIconId; + mIconName = keyParams.mIconName; mPopupKeys = keyParams.mPopupKeys; mPopupKeysColumnAndFlags = keyParams.mPopupKeysColumnAndFlags; mBackgroundType = keyParams.mBackgroundType; @@ -328,7 +327,7 @@ public class Key implements Comparable { mLabel = key.mLabel; mHintLabel = key.mHintLabel; mLabelFlags = key.mLabelFlags; - mIconId = key.mIconId; + mIconName = key.mIconName; mWidth = key.mWidth; mHeight = key.mHeight; mHorizontalGap = key.mHorizontalGap; @@ -378,7 +377,7 @@ public class Key implements Comparable { key.mCode, key.mLabel, key.mHintLabel, - key.mIconId, + key.mIconName, key.mBackgroundType, Arrays.hashCode(key.mPopupKeys), key.getOutputText(), @@ -405,7 +404,7 @@ public class Key implements Comparable { && o.mCode == mCode && TextUtils.equals(o.mLabel, mLabel) && TextUtils.equals(o.mHintLabel, mHintLabel) - && o.mIconId == mIconId + && o.mIconName == mIconName && o.mBackgroundType == mBackgroundType && Arrays.equals(o.mPopupKeys, mPopupKeys) && TextUtils.equals(o.getOutputText(), getOutputText()) @@ -444,9 +443,9 @@ public class Key implements Comparable { } public String toLongString() { - final int iconId = getIconId(); - final String topVisual = (iconId == KeyboardIconsSet.ICON_UNDEFINED) - ? KeyboardIconsSet.PREFIX_ICON + KeyboardIconsSet.getIconName(iconId) : getLabel(); + final String iconName = getIconName(); + final String topVisual = (iconName.equals(KeyboardIconsSet.NAME_UNDEFINED)) + ? KeyboardIconsSet.PREFIX_ICON + iconName : getLabel(); final String hintLabel = getHintLabel(); final String visual = (hintLabel == null) ? topVisual : topVisual + "^" + hintLabel; return toString() + " " + visual + "/" + backgroundName(mBackgroundType); @@ -702,16 +701,15 @@ public class Key implements Comparable { return (attrs != null) ? attrs.mAltCode : KeyCode.NOT_SPECIFIED; } - public int getIconId() { - return mIconId; + public String getIconName() { + return mIconName; } @Nullable public Drawable getIcon(final KeyboardIconsSet iconSet, final int alpha) { final OptionalAttributes attrs = mOptionalAttributes; - final int disabledIconId = (attrs != null) ? attrs.mDisabledIconId : ICON_UNDEFINED; - final int iconId = mEnabled ? getIconId() : disabledIconId; - final Drawable icon = iconSet.getIconDrawable(iconId); + final String iconName = mEnabled ? getIconName() : ((attrs != null) ? attrs.mDisabledIconName : KeyboardIconsSet.NAME_UNDEFINED); + final Drawable icon = iconSet.getIconDrawable(iconName); if (icon != null) { icon.setAlpha(alpha); } @@ -720,7 +718,7 @@ public class Key implements Comparable { @Nullable public Drawable getPreviewIcon(final KeyboardIconsSet iconSet) { - return iconSet.getIconDrawable(getIconId()); + return iconSet.getIconDrawable(getIconName()); } /** @@ -902,7 +900,7 @@ public class Key implements Comparable { public final Drawable selectBackgroundDrawable(@NonNull final Drawable keyBackground, @NonNull final Drawable functionalKeyBackground, @NonNull final Drawable spacebarBackground, - @NonNull final Drawable actionKeyBackground) { + @NonNull final Drawable actionKeyBackground) { final Drawable background; if (isAccentColored()) { background = actionKeyBackground; @@ -920,7 +918,7 @@ public class Key implements Comparable { public final boolean isAccentColored() { if (hasActionKeyBackground()) return true; - final String iconName = KeyboardIconsSet.getIconName(getIconId()); + final String iconName = getIconName(); return iconName.equals(KeyboardIconsSet.NAME_NEXT_KEY) || iconName.equals(KeyboardIconsSet.NAME_PREVIOUS_KEY) || iconName.equals(KeyboardIconsSet.NAME_CLIPBOARD_ACTION_KEY) @@ -943,8 +941,8 @@ public class Key implements Comparable { */ protected Spacer(final KeyboardParams params, final int x, final int y, final int width, final int height) { - super(null /* label */, ICON_UNDEFINED, KeyCode.NOT_SPECIFIED, null /* outputText */, - null /* hintLabel */, 0 /* labelFlags */, BACKGROUND_TYPE_EMPTY, x, y, width, + super(null, KeyboardIconsSet.NAME_UNDEFINED, KeyCode.NOT_SPECIFIED, null, + null, 0, BACKGROUND_TYPE_EMPTY, x, y, width, height, params.mHorizontalGap, params.mVerticalGap); } } @@ -968,7 +966,7 @@ public class Key implements Comparable { @Nullable public String mLabel; @Nullable public final String mHintLabel; public final int mLabelFlags; - public final int mIconId; + @NonNull public final String mIconName; @Nullable public PopupKeySpec[] mPopupKeys; public final int mPopupKeysColumnAndFlags; public int mBackgroundType; @@ -1062,7 +1060,7 @@ public class Key implements Comparable { mLabelFlags = labelFlags; mWidth = width; mHeight = params.mDefaultRowHeight; - mIconId = KeySpecParser.getIconId(keySpec); + mIconName = KeySpecParser.getIconName(keySpec); final boolean needsToUpcase = needsToUpcase(mLabelFlags, params.mId.mElementId); final Locale localeForUpcasing = params.mId.getLocale(); @@ -1167,7 +1165,7 @@ public class Key implements Comparable { : altCodeInAttr; mOptionalAttributes = OptionalAttributes.newInstance(outputText, altCode, // 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 // could be used e.g. for having a color gradient on key color mKeyVisualAttributes = null; @@ -1207,11 +1205,11 @@ public class Key implements Comparable { mLabel = label; 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; mCode = code; mEnabled = (code != KeyCode.NOT_SPECIFIED); - mIconId = KeyboardIconsSet.ICON_UNDEFINED; + mIconName = KeyboardIconsSet.NAME_UNDEFINED; mKeyVisualAttributes = null; } @@ -1225,7 +1223,7 @@ public class Key implements Comparable { mHintLabel = null; mKeyVisualAttributes = null; mOptionalAttributes = null; - mIconId = KeyboardIconsSet.ICON_UNDEFINED; + mIconName = KeyboardIconsSet.NAME_UNDEFINED; mBackgroundType = BACKGROUND_TYPE_NORMAL; mActionFlags = ACTION_FLAGS_NO_KEY_PREVIEW; mPopupKeys = null; @@ -1247,7 +1245,7 @@ public class Key implements Comparable { mLabel = keyParams.mLabel; mHintLabel = keyParams.mHintLabel; mLabelFlags = keyParams.mLabelFlags; - mIconId = keyParams.mIconId; + mIconName = keyParams.mIconName; mAbsoluteWidth = keyParams.mAbsoluteWidth; mAbsoluteHeight = keyParams.mAbsoluteHeight; mPopupKeys = keyParams.mPopupKeys; diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java b/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java index d5b38fb34..6eba7a46b 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java @@ -39,6 +39,7 @@ import helium314.keyboard.latin.common.StringUtils; import helium314.keyboard.latin.settings.Settings; import helium314.keyboard.latin.suggestions.MoreSuggestions; import helium314.keyboard.latin.suggestions.PopupSuggestionsView; +import helium314.keyboard.latin.utils.Log; import helium314.keyboard.latin.utils.TypefaceUtils; import java.util.HashSet; diff --git a/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt b/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt index ff79eb8e2..2f169242c 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt @@ -141,9 +141,9 @@ class ClipboardHistoryView @JvmOverloads constructor( } } - private fun setupDeleteKey(key: ImageButton, iconId: Int) { + private fun setupDeleteKey(key: ImageButton, icon: Drawable?) { key.apply { - setImageResource(iconId) + setImageDrawable(icon) Settings.getInstance().current.mColors.setBackground(this, ColorType.FUNCTIONAL_KEY_BACKGROUND) Settings.getInstance().current.mColors.setColor(this, ColorType.KEY_ICON) } @@ -189,7 +189,7 @@ class ClipboardHistoryView @JvmOverloads constructor( val params = KeyDrawParams() params.updateParams(clipboardLayoutParams.actionBarContentHeight, keyVisualAttr) setupAlphabetKey(alphabetKey, switchToAlphaLabel, params) - setupDeleteKey(deleteKey, iconSet.getIconResourceId(KeyboardIconsSet.NAME_DELETE_KEY)) + setupDeleteKey(deleteKey, iconSet.getIconDrawable(KeyboardIconsSet.NAME_DELETE_KEY)) setupClipKey(params) placeholderView.apply { diff --git a/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiPalettesView.java b/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiPalettesView.java index b93137599..a29412b9e 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiPalettesView.java +++ b/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiPalettesView.java @@ -360,10 +360,7 @@ public final class EmojiPalettesView extends LinearLayout final KeyVisualAttributes keyVisualAttr, final KeyboardIconsSet iconSet) { initialize(); - final int deleteIconResId = iconSet.getIconResourceId(KeyboardIconsSet.NAME_DELETE_KEY); - if (deleteIconResId != 0) { - mDeleteKey.setImageResource(deleteIconResId); - } + mDeleteKey.setImageDrawable(iconSet.getIconDrawable(KeyboardIconsSet.NAME_DELETE_KEY)); mEmojiLayoutParams.setActionBarProperties(findViewById(R.id.action_bar)); final KeyDrawParams params = new KeyDrawParams(); params.updateParams(mEmojiLayoutParams.getActionBarHeight(), keyVisualAttr); diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyPreviewView.java b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyPreviewView.java index 7c735810e..98b646f16 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyPreviewView.java +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyPreviewView.java @@ -43,11 +43,9 @@ public class KeyPreviewView extends AppCompatTextView { setGravity(Gravity.CENTER); } - public void setPreviewVisual(final Key key, final KeyboardIconsSet iconsSet, - final KeyDrawParams drawParams) { + public void setPreviewVisual(final Key key, final KeyboardIconsSet iconsSet, final KeyDrawParams drawParams) { // What we show as preview should match what we show on a key top in onDraw(). - final int iconId = key.getIconId(); - if (iconId != KeyboardIconsSet.ICON_UNDEFINED) { + if (!key.getIconName().equals(KeyboardIconsSet.NAME_UNDEFINED)) { setCompoundDrawables(null, null, null, key.getPreviewIcon(iconsSet)); setText(null); return; diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/KeySpecParser.java b/app/src/main/java/helium314/keyboard/keyboard/internal/KeySpecParser.java index a8515c66c..1c2ba1074 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/KeySpecParser.java +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/KeySpecParser.java @@ -221,18 +221,17 @@ public final class KeySpecParser { return defaultCode; } - public static int getIconId(@Nullable final String keySpec) { + @NonNull + public static String getIconName(@Nullable final String keySpec) { if (keySpec == null) { // TODO: Throw {@link KeySpecParserError} once Key.keyLabel attribute becomes mandatory. - return KeyboardIconsSet.ICON_UNDEFINED; + return KeyboardIconsSet.NAME_UNDEFINED; } if (!hasIcon(keySpec)) { - return KeyboardIconsSet.ICON_UNDEFINED; + return KeyboardIconsSet.NAME_UNDEFINED; } final int labelEnd = indexOfLabelEnd(keySpec); - final String iconName = getBeforeLabelEnd(keySpec, labelEnd) - .substring(KeyboardIconsSet.PREFIX_ICON.length()); - return KeyboardIconsSet.getIconId(iconName); + return getBeforeLabelEnd(keySpec, labelEnd).substring(KeyboardIconsSet.PREFIX_ICON.length()).intern(); } public static final class KeySpecParserError extends RuntimeException { diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardIconsSet.java b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardIconsSet.java deleted file mode 100644 index 9c6693788..000000000 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardIconsSet.java +++ /dev/null @@ -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 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()); - } - } -} diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardIconsSet.kt b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardIconsSet.kt new file mode 100644 index 000000000..f143bdcbb --- /dev/null +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardIconsSet.kt @@ -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(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)) } } + } +} diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/PopupKeySpec.java b/app/src/main/java/helium314/keyboard/keyboard/internal/PopupKeySpec.java index 645e002c9..946dc5ba6 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/PopupKeySpec.java +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/PopupKeySpec.java @@ -40,7 +40,8 @@ public final class PopupKeySpec { public final String mLabel; @Nullable public final String mOutputText; - public final int mIconId; + @NonNull + public final String mIconName; public PopupKeySpec(@NonNull final String popupKeySpec, boolean needsToUpperCase, @NonNull final Locale locale) { @@ -63,13 +64,13 @@ public final class PopupKeySpec { mOutputText = needsToUpperCase ? StringUtils.toTitleCaseOfKeyLabel(outputText, locale) : outputText; } - mIconId = KeySpecParser.getIconId(popupKeySpec); + mIconName = KeySpecParser.getIconName(popupKeySpec); } @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, + return new Key(mLabel, mIconName, mCode, mOutputText, null /* hintLabel */, labelFlags, Key.BACKGROUND_TYPE_NORMAL, x, y, params.mDefaultAbsoluteKeyWidth, params.mDefaultAbsoluteRowHeight, params.mHorizontalGap, params.mVerticalGap); } @@ -77,7 +78,7 @@ public final class PopupKeySpec { @Override public int hashCode() { int hashCode = 31 + mCode; - hashCode = hashCode * 31 + mIconId; + hashCode = hashCode * 31 + mIconName.hashCode(); final String label = mLabel; hashCode = hashCode * 31 + (label == null ? 0 : label.hashCode()); final String outputText = mOutputText; @@ -93,7 +94,7 @@ public final class PopupKeySpec { if (o instanceof PopupKeySpec) { final PopupKeySpec other = (PopupKeySpec)o; return mCode == other.mCode - && mIconId == other.mIconId + && mIconName.equals(other.mIconName) && TextUtils.equals(mLabel, other.mLabel) && TextUtils.equals(mOutputText, other.mOutputText); } @@ -102,8 +103,8 @@ public final class PopupKeySpec { @Override public String toString() { - final String label = (mIconId == KeyboardIconsSet.ICON_UNDEFINED ? mLabel - : KeyboardIconsSet.PREFIX_ICON + KeyboardIconsSet.getIconName(mIconId)); + final String label = (mIconName.equals(KeyboardIconsSet.NAME_UNDEFINED) ? mLabel + : KeyboardIconsSet.PREFIX_ICON + mIconName); final String output = (mCode == KeyCode.MULTIPLE_CODE_POINTS ? mOutputText : Constants.printableCode(mCode)); if (StringUtils.codePointCount(label) == 1 && label.codePointAt(0) == mCode) { diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/KeyboardParser.kt b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/KeyboardParser.kt index 60958811d..dca131e79 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/KeyboardParser.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/KeyboardParser.kt @@ -467,7 +467,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co } 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 && params.mId.mHeight == AndroidSpellCheckerService.SPELLCHECKER_DUMMY_KEYBOARD_HEIGHT && !params.mId.mSubtype.hasExtraValue(Constants.Subtype.ExtraValue.EMOJI_CAPABLE) diff --git a/app/src/main/java/helium314/keyboard/latin/suggestions/MoreSuggestions.java b/app/src/main/java/helium314/keyboard/latin/suggestions/MoreSuggestions.java index 28e2f57b3..93030def7 100644 --- a/app/src/main/java/helium314/keyboard/latin/suggestions/MoreSuggestions.java +++ b/app/src/main/java/helium314/keyboard/latin/suggestions/MoreSuggestions.java @@ -230,8 +230,8 @@ public final class MoreSuggestions extends Keyboard { public MoreSuggestionKey(final String word, final String info, final int index, final MoreSuggestionsParam params) { - super(word /* label */, KeyboardIconsSet.ICON_UNDEFINED, KeyCode.MULTIPLE_CODE_POINTS, - word /* outputText */, info, 0 /* labelFlags */, Key.BACKGROUND_TYPE_NORMAL, + super(word, KeyboardIconsSet.NAME_UNDEFINED, KeyCode.MULTIPLE_CODE_POINTS, + word, info, 0, Key.BACKGROUND_TYPE_NORMAL, params.getX(index), params.getY(index), params.getWidth(index), params.mDefaultAbsoluteRowHeight, params.mHorizontalGap, params.mVerticalGap); mSuggestedWordIndex = index; diff --git a/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt b/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt index 672cb144f..3ec59fcb7 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt @@ -10,7 +10,6 @@ import android.widget.ImageView import androidx.appcompat.view.ContextThemeWrapper import androidx.core.content.edit import helium314.keyboard.keyboard.KeyboardTheme -import helium314.keyboard.keyboard.internal.KeyboardIconsSet import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode import helium314.keyboard.latin.R import helium314.keyboard.latin.settings.Settings @@ -74,8 +73,7 @@ fun getCodeForToolbarKeyLongClick(key: ToolbarKey) = when (key) { else -> KeyCode.UNSPECIFIED } -// todo: get the icons from KeyboardIconsSet (but currently it's loaded too late) -private fun getStyleableIconId(key: ToolbarKey) = when (key) { +fun getStyleableIconId(key: ToolbarKey) = when (key) { VOICE -> R.styleable.Keyboard_iconShortcutKey SETTINGS -> R.styleable.Keyboard_iconSettingsKey CLIPBOARD -> R.styleable.Keyboard_iconClipboardNormalKey