Add the Extra Keys option

Allows to add more keys to the keyboard from a predefined list.
The implementation doesn't use MultiSelectListPreference because it
doesn't seem possible to change the item layout to properly show the
rendered symbols.
This commit is contained in:
Jules Aguillon 2022-09-19 11:41:18 +02:00
parent 617f0878bc
commit 25a6e71ee8
8 changed files with 114 additions and 16 deletions

6
res/values/attrs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ExtraKeyCheckBoxPreference">
<attr name="index" format="integer"/>
</declare-styleable>
</resources>

View File

@ -12,6 +12,7 @@
<string name="pref_accents_e_none">Hide accents</string> <string name="pref_accents_e_none">Hide accents</string>
<string name="pref_autocapitalisation_title">Automatic capitalisation</string> <string name="pref_autocapitalisation_title">Automatic capitalisation</string>
<string name="pref_autocapitalisation_summary">Press Shift at the beginning of a sentence</string> <string name="pref_autocapitalisation_summary">Press Shift at the beginning of a sentence</string>
<string name="pref_extra_keys_title">Add keys to the keyboard</string>
<string name="pref_programming_layout_title">Keyboard layout for programming</string> <string name="pref_programming_layout_title">Keyboard layout for programming</string>
<string name="pref_programming_layout_none">None</string> <string name="pref_programming_layout_none">None</string>
<string name="pref_category_typing">Typing</string> <string name="pref_category_typing">Typing</string>

View File

@ -1,9 +1,26 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<PreferenceCategory android:title="@string/pref_category_layout"> <PreferenceCategory android:title="@string/pref_category_layout">
<ListPreference android:key="layout" android:title="@string/pref_layout_title" android:summary="%s" android:defaultValue="system" android:entries="@array/pref_layout_entries" android:entryValues="@array/pref_layout_values"/> <ListPreference android:key="layout" android:title="@string/pref_layout_title" android:summary="%s" android:defaultValue="system" android:entries="@array/pref_layout_entries" android:entryValues="@array/pref_layout_values"/>
<ListPreference android:key="accents" android:title="@string/pref_accents_title" android:summary="%s" android:defaultValue="1" android:entries="@array/pref_accents_entries" android:entryValues="@array/pref_accents_values"/> <ListPreference android:key="accents" android:title="@string/pref_accents_title" android:summary="%s" android:defaultValue="1" android:entries="@array/pref_accents_entries" android:entryValues="@array/pref_accents_values"/>
<ListPreference android:key="programming_layout" android:title="@string/pref_programming_layout_title" android:summary="%s" android:defaultValue="none" android:entries="@array/pref_programming_layout_entries" android:entryValues="@array/pref_programming_layout_values"/> <ListPreference android:key="programming_layout" android:title="@string/pref_programming_layout_title" android:summary="%s" android:defaultValue="none" android:entries="@array/pref_programming_layout_entries" android:entryValues="@array/pref_programming_layout_values"/>
<PreferenceScreen android:title="@string/pref_extra_keys_title">
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="0"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="1"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="2"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="3"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="4"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="5"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="6"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="7"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="8"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="9"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="10"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="11"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="12"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="13"/>
<juloo.keyboard2.ExtraKeyCheckBoxPreference app:index="14"/>
</PreferenceScreen>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="@string/pref_category_typing"> <PreferenceCategory android:title="@string/pref_category_typing">
<CheckBoxPreference android:key="autocapitalisation" android:title="@string/pref_autocapitalisation_title" android:summary="@string/pref_autocapitalisation_summary" android:defaultValue="true"/> <CheckBoxPreference android:key="autocapitalisation" android:title="@string/pref_autocapitalisation_title" android:summary="@string/pref_autocapitalisation_summary" android:defaultValue="true"/>

View File

@ -47,7 +47,8 @@ final class Config
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<KeyValue> extra_keys; // 'null' means all the keys public Set<KeyValue> extra_keys_subtype;
public Set<KeyValue> extra_keys_param;
public final IKeyEventHandler handler; public final IKeyEventHandler handler;
@ -81,7 +82,7 @@ final class Config
actionLabel = null; actionLabel = null;
actionId = 0; actionId = 0;
swapEnterActionKey = false; swapEnterActionKey = false;
extra_keys = null; extra_keys_subtype = null;
handler = h; handler = h;
} }
@ -149,6 +150,7 @@ final class Config
accents = Integer.valueOf(prefs.getString("accents", "1")); accents = Integer.valueOf(prefs.getString("accents", "1"));
theme = getThemeId(res, prefs.getString("theme", "")); theme = getThemeId(res, prefs.getString("theme", ""));
autocapitalisation = prefs.getBoolean("autocapitalisation", true); autocapitalisation = prefs.getBoolean("autocapitalisation", true);
extra_keys_param = ExtraKeyCheckBoxPreference.get_extra_keys(prefs);
} }
/** Update the layout according to the configuration. /** Update the layout according to the configuration.
@ -164,7 +166,9 @@ final class Config
KeyValue.getKeyByName("action").withSymbol(actionLabel); KeyValue.getKeyByName("action").withSymbol(actionLabel);
// Extra keys are removed from the set as they are encountered during the // Extra keys are removed from the set as they are encountered during the
// first iteration then automatically added. // first iteration then automatically added.
final Set<KeyValue> extra_keys = new HashSet<KeyValue>(this.extra_keys); final Set<KeyValue> extra_keys = new HashSet<KeyValue>();
extra_keys.addAll(extra_keys_subtype);
extra_keys.addAll(extra_keys_param);
KeyboardData kw = original_kw.mapKeys(new KeyboardData.MapKeyValues() { KeyboardData kw = original_kw.mapKeys(new KeyboardData.MapKeyValues() {
public KeyValue apply(KeyValue key, boolean localized) public KeyValue apply(KeyValue key, boolean localized)
{ {

View File

@ -18,7 +18,7 @@ public class EmojiKeyButton extends Button
_key = (key_name == null) ? null : KeyValue.getKeyByName(key_name); _key = (key_name == null) ? null : KeyValue.getKeyByName(key_name);
setText(_key.getString()); setText(_key.getString());
if (_key.hasFlags(KeyValue.FLAG_KEY_FONT)) if (_key.hasFlags(KeyValue.FLAG_KEY_FONT))
setTypeface(Theme.getSpecialKeyFont(context)); setTypeface(Theme.getKeyFont(context));
} }
public void onClick(View v) public void onClick(View v)

View File

@ -0,0 +1,72 @@
package juloo.keyboard2;
import android.content.Context;
import android.content.res.TypedArray;
import android.content.SharedPreferences;
import android.preference.CheckBoxPreference;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
import java.util.HashSet;
import java.util.Set;
public class ExtraKeyCheckBoxPreference extends CheckBoxPreference
{
public static String[] extra_keys = new String[]
{
"accent_aigu",
"accent_grave",
"accent_double_aigu",
"accent_dot_above",
"accent_circonflexe",
"accent_tilde",
"accent_cedille",
"accent_trema",
"accent_ring",
"accent_caron",
"accent_macron",
"accent_ogonek",
"",
"ß",
"£"
};
boolean _key_font;
public ExtraKeyCheckBoxPreference(Context context, AttributeSet attrs)
{
super(context, attrs);
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ExtraKeyCheckBoxPreference);
int index = a.getInteger(R.styleable.ExtraKeyCheckBoxPreference_index, 0);
a.recycle();
String key_name = extra_keys[index];
setKey(pref_key_of_key_name(key_name));
KeyValue kv = KeyValue.getKeyByName(key_name);
setTitle(kv.getString());
_key_font = kv.hasFlags(KeyValue.FLAG_KEY_FONT);
}
@Override
protected void onBindView(View view)
{
super.onBindView(view);
TextView title = (TextView)view.findViewById(android.R.id.title);
title.setTypeface(_key_font ? Theme.getKeyFont(getContext()) : null);
}
static String pref_key_of_key_name(String key_name)
{
return "extra_key_" + key_name;
}
public static Set<KeyValue> get_extra_keys(SharedPreferences prefs)
{
HashSet<KeyValue> ks = new HashSet<KeyValue>();
for (String key_name : extra_keys)
{
if (prefs.getBoolean(pref_key_of_key_name(key_name), false))
ks.add(KeyValue.getKeyByName(key_name));
}
return ks;
}
}

View File

@ -117,7 +117,7 @@ public class Keyboard2 extends InputMethodService
case 4: break; case 4: break;
default: throw new IllegalArgumentException(); default: throw new IllegalArgumentException();
} }
_config.extra_keys = extra_keys; _config.extra_keys_subtype = extra_keys;
if (enabled_subtypes.size() > 1) if (enabled_subtypes.size() > 1)
_config.shouldOfferSwitchingToNextInputMethod = true; _config.shouldOfferSwitchingToNextInputMethod = true;
} }
@ -127,8 +127,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.extra_keys = null; break; case 1: case 2: case 3: _config.extra_keys_subtype = null; break;
case 4: _config.extra_keys = new HashSet<KeyValue>(); break; case 4: _config.extra_keys_subtype = new HashSet<KeyValue>(); 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;

View File

@ -42,7 +42,7 @@ public class Theme
s.recycle(); s.recycle();
_keyLabelPaint = initLabelPaint(Paint.Align.CENTER, null); _keyLabelPaint = initLabelPaint(Paint.Align.CENTER, null);
_keySubLabelPaint = initLabelPaint(Paint.Align.LEFT, null); _keySubLabelPaint = initLabelPaint(Paint.Align.LEFT, null);
Typeface specialKeyFont = getSpecialKeyFont(context); Typeface specialKeyFont = getKeyFont(context);
_specialKeyLabelPaint = initLabelPaint(Paint.Align.CENTER, specialKeyFont); _specialKeyLabelPaint = initLabelPaint(Paint.Align.CENTER, specialKeyFont);
_specialKeySubLabelPaint = initLabelPaint(Paint.Align.LEFT, specialKeyFont); _specialKeySubLabelPaint = initLabelPaint(Paint.Align.LEFT, specialKeyFont);
} }
@ -69,14 +69,12 @@ public class Theme
return (paint); return (paint);
} }
private static Typeface _specialKeyFont = null; private static Typeface _key_font = null;
static public Typeface getSpecialKeyFont(Context context) static public Typeface getKeyFont(Context context)
{ {
if (_specialKeyFont == null) if (_key_font == null)
{ _key_font = Typeface.createFromAsset(context.getAssets(), "special_font.ttf");
_specialKeyFont = Typeface.createFromAsset(context.getAssets(), "special_font.ttf"); return _key_font;
}
return _specialKeyFont;
} }
} }