Define localized keys as a set instead of flags

Using flags for removing keys like € and ß need too many flags and won't
scale to more localized keys.
This commit is contained in:
Jules Aguillon 2022-03-13 00:14:18 +01:00
parent 2ea256e769
commit ee6e892ef4
4 changed files with 49 additions and 73 deletions

View File

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity="juloo.keyboard2.SettingsActivity" android:supportsSwitchingToNextInputMethod="true"> <input-method xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity="juloo.keyboard2.SettingsActivity" android:supportsSwitchingToNextInputMethod="true">
<subtype android:label="%s" android:languageTag="bg" android:imeSubtypeLocale="bg_BG" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=bgph1,extra_keys=euro"/> <subtype android:label="%s" android:languageTag="bg" android:imeSubtypeLocale="bg_BG" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=bgph1,extra_keys="/>
<subtype android:label="%s" android:languageTag="de" android:imeSubtypeLocale="de_DE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwertz,extra_keys=trema|szlig|euro"/> <subtype android:label="%s" android:languageTag="de" android:imeSubtypeLocale="de_DE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwertz,extra_keys=accent_trema|ß|€"/>
<subtype android:label="%s" android:languageTag="en-GB" android:imeSubtypeLocale="en_GB" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty,extra_keys=pound|euro"/> <subtype android:label="%s" android:languageTag="en-GB" android:imeSubtypeLocale="en_GB" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty,extra_keys=£|€"/>
<subtype android:label="%s" android:languageTag="en-US" android:imeSubtypeLocale="en_US" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty"/> <subtype android:label="%s" android:languageTag="en-US" android:imeSubtypeLocale="en_US" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty"/>
<subtype android:label="%s" android:languageTag="es" android:imeSubtypeLocale="es_ES" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty_es,extra_keys=grave|aigu|tilde|trema|euro"/> <subtype android:label="%s" android:languageTag="es" android:imeSubtypeLocale="es_ES" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty_es,extra_keys=accent_grave|accent_aigu|accent_tilde|accent_trema|€"/>
<subtype android:label="%s" android:languageTag="fr" android:imeSubtypeLocale="fr_FR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=azerty,extra_keys=grave|aigu|circonflexe|cedille|trema|euro"/> <subtype android:label="%s" android:languageTag="fr" android:imeSubtypeLocale="fr_FR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=azerty,extra_keys=accent_grave|accent_aigu|accent_circonflexe|accent_cedille|accent_trema|€"/>
<subtype android:label="%s" android:languageTag="it" android:imeSubtypeLocale="it_IT" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty,extra_keys=grave|aigu|euro"/> <subtype android:label="%s" android:languageTag="it" android:imeSubtypeLocale="it_IT" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty,extra_keys=accent_grave|accent_aigu|€"/>
<subtype android:label="%s" android:languageTag="lv" android:imeSubtypeLocale="lv_LV" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty_lv,extra_keys=caron|cedille|macron|euro"/> <subtype android:label="%s" android:languageTag="lv" android:imeSubtypeLocale="lv_LV" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty_lv,extra_keys=accent_caron|accent_cedille|accent_macron|€"/>
<subtype android:label="%s" android:languageTag="pt" android:imeSubtypeLocale="pt_BR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty,extra_keys=aigu|cedille|circonflexe|grave|tilde|euro"/> <subtype android:label="%s" android:languageTag="pt" android:imeSubtypeLocale="pt_BR" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty,extra_keys=accent_aigu|accent_cedille|accent_circonflexe|accent_grave|accent_tilde|€"/>
<subtype android:label="%s" android:languageTag="ru" android:imeSubtypeLocale="ru_RU" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=ru_jcuken"/> <subtype android:label="%s" android:languageTag="ru" android:imeSubtypeLocale="ru_RU" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=ru_jcuken"/>
<subtype android:label="%s" android:languageTag="sv" android:imeSubtypeLocale="sv_SE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty,extra_keys=aigu|trema|ring|euro"/> <subtype android:label="%s" android:languageTag="sv" android:imeSubtypeLocale="sv_SE" android:imeSubtypeMode="keyboard" android:isAsciiCapable="true" android:imeSubtypeExtraValue="default_layout=qwerty,extra_keys=accent_aigu|accent_trema|accent_ring|€"/>
</input-method> </input-method>

View File

@ -9,6 +9,8 @@ import android.preference.PreferenceManager;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.KeyEvent; import android.view.KeyEvent;
import java.util.Set;
import java.util.HashSet;
final class Config final class Config
{ {
@ -40,10 +42,10 @@ final class Config
// Dynamically set // Dynamically set
public boolean shouldOfferSwitchingToNextInputMethod; public boolean shouldOfferSwitchingToNextInputMethod;
public int key_flags_to_remove;
public String actionLabel; // Might be 'null' public String actionLabel; // Might be 'null'
public int actionId; // Meaningful only when 'actionLabel' isn't 'null' public int actionId; // Meaningful only when 'actionLabel' isn't 'null'
public boolean swapEnterActionKey; // Swap the "enter" and "action" keys public boolean swapEnterActionKey; // Swap the "enter" and "action" keys
public Set<String> extra_keys; // 'null' means all the keys
public final IKeyEventHandler handler; public final IKeyEventHandler handler;
@ -73,10 +75,10 @@ final class Config
refresh(context); refresh(context);
// initialized later // initialized later
shouldOfferSwitchingToNextInputMethod = false; shouldOfferSwitchingToNextInputMethod = false;
key_flags_to_remove = 0;
actionLabel = null; actionLabel = null;
actionId = 0; actionId = 0;
swapEnterActionKey = false; swapEnterActionKey = false;
extra_keys = null;
handler = h; handler = h;
} }
@ -128,7 +130,7 @@ final class Config
/** Update the layout according to the configuration. /** Update the layout according to the configuration.
* - Remove the switching key if it isn't needed * - Remove the switching key if it isn't needed
* - Remove keys from other locales * - Remove keys from other locales (not in 'extra_keys')
* - Replace the action key to show the right label * - Replace the action key to show the right label
* - Swap the enter and action keys * - Swap the enter and action keys
*/ */
@ -152,7 +154,9 @@ final class Config
default: default:
if (key.flags != 0) if (key.flags != 0)
{ {
if ((key.flags & key_flags_to_remove) != 0) if ((key.flags & KeyValue.FLAG_LOCALIZED) != 0 &&
extra_keys != null &&
!extra_keys.contains(key.name))
return null; return null;
if ((key.flags & lockable_modifiers) != 0) if ((key.flags & lockable_modifiers) != 0)
return key.withFlags(key.flags | KeyValue.FLAG_LOCK); return key.withFlags(key.flags | KeyValue.FLAG_LOCK);
@ -206,27 +210,6 @@ final class Config
} }
} }
/* Used for the accents option. */
public static int extra_key_flag_of_name(String name)
{
switch (name)
{
case "aigu": return KeyValue.FLAG_ACCENT2;
case "caron": return KeyValue.FLAG_ACCENT_CARON;
case "cedille": return KeyValue.FLAG_ACCENT5;
case "circonflexe": return KeyValue.FLAG_ACCENT3;
case "grave": return KeyValue.FLAG_ACCENT1;
case "macron": return KeyValue.FLAG_ACCENT_MACRON;
case "ring": return KeyValue.FLAG_ACCENT_RING;
case "szlig": return KeyValue.FLAG_LANG_SZLIG;
case "euro": return KeyValue.FLAG_LANG_EURO;
case "pound": return KeyValue.FLAG_LANG_POUND;
case "tilde": return KeyValue.FLAG_ACCENT4;
case "trema": return KeyValue.FLAG_ACCENT6;
default: throw new RuntimeException(name);
}
}
public static int themeId_of_string(String name) public static int themeId_of_string(String name)
{ {
switch (name) switch (name)

View File

@ -56,19 +56,8 @@ class KeyValue
FLAG_ACCENT_CARON | FLAG_ACCENT_MACRON | FLAG_ACCENT_SUPERSCRIPT | FLAG_ACCENT_CARON | FLAG_ACCENT_MACRON | FLAG_ACCENT_SUPERSCRIPT |
FLAG_ACCENT_SUBSCRIPT | FLAG_ACCENT_ORDINAL | FLAG_ACCENT_RING; FLAG_ACCENT_SUBSCRIPT | FLAG_ACCENT_ORDINAL | FLAG_ACCENT_RING;
// Language specific keys // Language specific keys that are removed from the keyboard by default
public static final int FLAG_LANG_SZLIG = (1 << 25); public static final int FLAG_LOCALIZED = (1 << 25);
public static final int FLAG_LANG_EURO = (1 << 29);
public static final int FLAG_LANG_POUND = (1 << 30);
public static final int FLAGS_LANGS = FLAG_LANG_SZLIG | FLAG_LANG_EURO |
FLAG_LANG_POUND;
public static final int FLAGS_NOT_HIDDEN_ACCENTS = FLAG_ACCENT_SUPERSCRIPT |
FLAG_ACCENT_SUBSCRIPT | FLAG_ACCENT_ORDINAL;
// Keys that have to be enabled per language
public static final int FLAGS_HIDDEN_KEYS =
(FLAGS_ACCENTS & ~FLAGS_NOT_HIDDEN_ACCENTS) | FLAGS_LANGS;
public final String name; public final String name;
public final String symbol; public final String symbol;
@ -167,15 +156,15 @@ class KeyValue
FLAG_SHIFT | FLAG_KEY_FONT | FLAG_SMALLER_FONT); FLAG_SHIFT | FLAG_KEY_FONT | FLAG_SMALLER_FONT);
addModifierKey("ctrl", "Ctrl", FLAG_CTRL | FLAG_SMALLER_FONT); addModifierKey("ctrl", "Ctrl", FLAG_CTRL | FLAG_SMALLER_FONT);
addModifierKey("alt", "Alt", FLAG_ALT | FLAG_SMALLER_FONT); addModifierKey("alt", "Alt", FLAG_ALT | FLAG_SMALLER_FONT);
addModifierKey("accent_aigu", "◌́", FLAG_ACCENT2); addModifierKey("accent_aigu", "◌́", FLAG_ACCENT2 | FLAG_LOCALIZED);
addModifierKey("accent_caron", "◌̌", FLAG_ACCENT_CARON); addModifierKey("accent_caron", "◌̌", FLAG_ACCENT_CARON | FLAG_LOCALIZED);
addModifierKey("accent_cedille", "◌̧", FLAG_ACCENT5); addModifierKey("accent_cedille", "◌̧", FLAG_ACCENT5 | FLAG_LOCALIZED);
addModifierKey("accent_circonflexe", "◌̂", FLAG_ACCENT3); addModifierKey("accent_circonflexe", "◌̂", FLAG_ACCENT3 | FLAG_LOCALIZED);
addModifierKey("accent_grave", "◌̀", FLAG_ACCENT1); addModifierKey("accent_grave", "◌̀", FLAG_ACCENT1 | FLAG_LOCALIZED);
addModifierKey("accent_macron", "◌̄", FLAG_ACCENT_MACRON); addModifierKey("accent_macron", "◌̄", FLAG_ACCENT_MACRON | FLAG_LOCALIZED);
addModifierKey("accent_tilde", "◌̃", FLAG_ACCENT4); addModifierKey("accent_tilde", "◌̃", FLAG_ACCENT4 | FLAG_LOCALIZED);
addModifierKey("accent_trema", "◌̈", FLAG_ACCENT6); addModifierKey("accent_trema", "◌̈", FLAG_ACCENT6 | FLAG_LOCALIZED);
addModifierKey("accent_ring", "◌̊", FLAG_ACCENT_RING); addModifierKey("accent_ring", "◌̊", FLAG_ACCENT_RING | FLAG_LOCALIZED);
addModifierKey("superscript", "◌͆", FLAG_ACCENT_SUPERSCRIPT); addModifierKey("superscript", "◌͆", FLAG_ACCENT_SUPERSCRIPT);
addModifierKey("subscript", "◌̺", FLAG_ACCENT_SUBSCRIPT); addModifierKey("subscript", "◌̺", FLAG_ACCENT_SUBSCRIPT);
addModifierKey("ordinal", "ºʳᵈ", FLAG_ACCENT_ORDINAL | FLAG_SMALLER_FONT); addModifierKey("ordinal", "ºʳᵈ", FLAG_ACCENT_ORDINAL | FLAG_SMALLER_FONT);
@ -235,9 +224,9 @@ class KeyValue
addCharKey('#', KeyEvent.KEYCODE_POUND); addCharKey('#', KeyEvent.KEYCODE_POUND);
addCharKey('(', KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN); addCharKey('(', KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN);
addCharKey(')', KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN); addCharKey(')', KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN);
addCharKey('ß', EVENT_NONE, FLAG_LANG_SZLIG); addCharKey('ß', EVENT_NONE, FLAG_LOCALIZED);
addCharKey('€', EVENT_NONE, FLAG_LANG_EURO); addCharKey('€', EVENT_NONE, FLAG_LOCALIZED);
addCharKey('£', EVENT_NONE, FLAG_LANG_POUND); addCharKey('£', EVENT_NONE, FLAG_LOCALIZED);
addSpecialKey("config", "\uE806", EVENT_CONFIG, FLAG_KEY_FONT | FLAG_SMALLER_FONT); addSpecialKey("config", "\uE806", EVENT_CONFIG, FLAG_KEY_FONT | FLAG_SMALLER_FONT);
addSpecialKey("switch_text", "ABC", EVENT_SWITCH_TEXT); addSpecialKey("switch_text", "ABC", EVENT_SWITCH_TEXT);

View File

@ -19,6 +19,8 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewParent; import android.view.ViewParent;
import java.util.List; import java.util.List;
import java.util.HashSet;
import java.util.Set;
public class Keyboard2 extends InputMethodService public class Keyboard2 extends InputMethodService
implements SharedPreferences.OnSharedPreferenceChangeListener implements SharedPreferences.OnSharedPreferenceChangeListener
@ -70,32 +72,34 @@ public class Keyboard2 extends InputMethodService
_currentTextLayout = l; _currentTextLayout = l;
} }
private int extra_keys_of_subtype(InputMethodSubtype subtype) private void extra_keys_of_subtype(Set<String> dst, InputMethodSubtype subtype)
{ {
String extra_keys = subtype.getExtraValueOf("extra_keys"); String extra_keys = subtype.getExtraValueOf("extra_keys");
int flags = 0; if (extra_keys == null)
if (extra_keys != null) return;
for (String acc : extra_keys.split("\\|")) String[] ks = extra_keys.split("\\|");
flags |= Config.extra_key_flag_of_name(acc); for (int i = 0; i < ks.length; i++)
return flags; dst.add(ks[i]);
} }
private void refreshAccentsOption(InputMethodManager imm, InputMethodSubtype subtype) private void refreshAccentsOption(InputMethodManager imm, InputMethodSubtype subtype)
{ {
int to_keep = 0; HashSet<String> extra_keys = new HashSet<String>();
switch (_config.accents) switch (_config.accents)
{ {
case 1: case 1:
to_keep |= extra_keys_of_subtype(subtype); extra_keys_of_subtype(extra_keys, subtype);
for (InputMethodSubtype s : getEnabledSubtypes(imm)) for (InputMethodSubtype s : getEnabledSubtypes(imm))
to_keep |= extra_keys_of_subtype(s); extra_keys_of_subtype(extra_keys, s);
break; break;
case 2: to_keep |= extra_keys_of_subtype(subtype); break; case 2:
case 3: to_keep = KeyValue.FLAGS_HIDDEN_KEYS; break; extra_keys_of_subtype(extra_keys, subtype);
break;
case 3: extra_keys = null; break;
case 4: break; case 4: break;
default: throw new IllegalArgumentException(); default: throw new IllegalArgumentException();
} }
_config.key_flags_to_remove = ~to_keep & KeyValue.FLAGS_HIDDEN_KEYS; _config.extra_keys = extra_keys;
} }
private void refreshSubtypeLegacyFallback() private void refreshSubtypeLegacyFallback()
@ -103,8 +107,8 @@ public class Keyboard2 extends InputMethodService
// Fallback for the accents option: Only respect the "None" case // Fallback for the accents option: Only respect the "None" case
switch (_config.accents) switch (_config.accents)
{ {
case 1: case 2: case 3: _config.key_flags_to_remove = 0; break; case 1: case 2: case 3: _config.extra_keys = null; break;
case 4: _config.key_flags_to_remove = KeyValue.FLAGS_HIDDEN_KEYS; break; case 4: _config.extra_keys = new HashSet<String>(); break;
} }
// Fallback for the layout option: Use qwerty in the "system settings" case // Fallback for the layout option: Use qwerty in the "system settings" case
_currentTextLayout = (_config.layout == -1) ? R.xml.qwerty : _config.layout; _currentTextLayout = (_config.layout == -1) ? R.xml.qwerty : _config.layout;