2015-10-29 12:49:40 +01:00
|
|
|
package juloo.keyboard2;
|
|
|
|
|
|
|
|
import android.content.SharedPreferences;
|
2022-11-13 16:18:08 +01:00
|
|
|
import android.content.res.Configuration;
|
|
|
|
import android.content.res.Resources;
|
2021-12-28 16:47:19 +01:00
|
|
|
import android.util.DisplayMetrics;
|
2015-10-29 12:49:40 +01:00
|
|
|
import android.util.TypedValue;
|
2022-03-05 18:15:36 +01:00
|
|
|
import android.view.KeyEvent;
|
2023-07-29 18:37:06 +02:00
|
|
|
import java.util.ArrayList;
|
2023-06-25 16:34:05 +02:00
|
|
|
import java.util.Arrays;
|
2023-09-15 18:00:27 +02:00
|
|
|
import java.util.HashMap;
|
2022-11-13 16:18:08 +01:00
|
|
|
import java.util.HashSet;
|
2023-06-25 16:34:05 +02:00
|
|
|
import java.util.List;
|
2023-09-15 18:00:27 +02:00
|
|
|
import java.util.Map;
|
2022-03-13 00:14:18 +01:00
|
|
|
import java.util.Set;
|
2024-01-13 20:59:05 +01:00
|
|
|
import juloo.keyboard2.prefs.CustomExtraKeysPreference;
|
|
|
|
import juloo.keyboard2.prefs.ExtraKeysPreference;
|
|
|
|
import juloo.keyboard2.prefs.LayoutsPreference;
|
2015-10-29 12:49:40 +01:00
|
|
|
|
2024-01-13 20:59:05 +01:00
|
|
|
public final class Config
|
2015-10-29 12:49:40 +01:00
|
|
|
{
|
2022-11-11 14:27:02 +01:00
|
|
|
private final SharedPreferences _prefs;
|
|
|
|
|
2021-05-09 00:09:10 +02:00
|
|
|
// From resources
|
2021-12-19 19:44:27 +01:00
|
|
|
public final float marginTop;
|
|
|
|
public final float keyPadding;
|
2015-10-29 12:49:40 +01:00
|
|
|
|
2022-02-27 01:50:24 +01:00
|
|
|
public final float labelTextSize;
|
|
|
|
public final float sublabelTextSize;
|
|
|
|
|
2024-05-29 11:56:26 +02:00
|
|
|
public final KeyboardData.Row bottom_row;
|
|
|
|
public final KeyboardData.Row number_row;
|
|
|
|
public final KeyboardData num_pad;
|
|
|
|
|
2021-05-09 00:09:10 +02:00
|
|
|
// From preferences
|
2023-07-29 18:37:06 +02:00
|
|
|
/** [null] represent the [system] layout. */
|
|
|
|
public List<KeyboardData> layouts;
|
2022-09-25 02:23:33 +02:00
|
|
|
public boolean show_numpad = false;
|
2022-12-10 19:39:22 +01:00
|
|
|
// From the 'numpad_layout' option, also apply to the numeric pane.
|
|
|
|
public boolean inverse_numpad = false;
|
2024-05-29 11:56:26 +02:00
|
|
|
public boolean add_number_row;
|
2021-12-30 22:22:25 +01:00
|
|
|
public float swipe_dist_px;
|
2023-01-22 23:03:30 +01:00
|
|
|
public float slide_step_px;
|
2024-01-09 00:43:28 +01:00
|
|
|
// Let the system handle vibration when false.
|
|
|
|
public boolean vibrate_custom;
|
|
|
|
// Control the vibration if [vibrate_custom] is true.
|
|
|
|
public long vibrate_duration;
|
2021-12-19 19:44:27 +01:00
|
|
|
public long longPressTimeout;
|
|
|
|
public long longPressInterval;
|
2024-06-30 00:24:39 +02:00
|
|
|
public boolean keyrepeat_enabled;
|
2023-01-15 19:19:07 +01:00
|
|
|
public float margin_bottom;
|
2021-12-19 19:44:27 +01:00
|
|
|
public float keyHeight;
|
2023-01-15 19:11:08 +01:00
|
|
|
public float horizontal_margin;
|
2024-01-28 19:38:29 +01:00
|
|
|
public float key_vertical_margin;
|
|
|
|
public float key_horizontal_margin;
|
2022-11-11 19:47:37 +01:00
|
|
|
public int labelBrightness; // 0 - 255
|
2022-12-11 22:10:00 +01:00
|
|
|
public int keyboardOpacity; // 0 - 255
|
2024-02-10 11:38:46 +01:00
|
|
|
public float customBorderRadius; // 0 - 1
|
|
|
|
public float customBorderLineWidth; // dp
|
2022-12-11 22:10:00 +01:00
|
|
|
public int keyOpacity; // 0 - 255
|
|
|
|
public int keyActivatedOpacity; // 0 - 255
|
2022-11-06 19:34:57 +01:00
|
|
|
public boolean double_tap_lock_shift;
|
2021-04-24 23:22:25 +02:00
|
|
|
public float characterSize; // Ratio
|
2021-12-30 00:26:05 +01:00
|
|
|
public int theme; // Values are R.style.*
|
2022-07-24 23:44:37 +02:00
|
|
|
public boolean autocapitalisation;
|
2023-02-12 23:20:11 +01:00
|
|
|
public boolean switch_input_immediate;
|
2023-07-29 17:29:45 +02:00
|
|
|
public boolean pin_entry_enabled;
|
2024-02-10 11:38:46 +01:00
|
|
|
public boolean borderConfig;
|
2024-06-09 14:25:19 +02:00
|
|
|
public int circle_sensitivity;
|
2024-07-06 22:16:37 +02:00
|
|
|
public boolean clipboard_history_enabled;
|
2015-10-29 12:49:40 +01:00
|
|
|
|
2021-05-09 00:09:10 +02:00
|
|
|
// Dynamically set
|
2023-06-03 18:35:16 +02:00
|
|
|
public boolean shouldOfferVoiceTyping;
|
2022-01-09 20:26:06 +01:00
|
|
|
public String actionLabel; // Might be 'null'
|
|
|
|
public int actionId; // Meaningful only when 'actionLabel' isn't 'null'
|
2022-01-10 00:27:22 +01:00
|
|
|
public boolean swapEnterActionKey; // Swap the "enter" and "action" keys
|
2023-06-24 23:29:24 +02:00
|
|
|
public ExtraKeys extra_keys_subtype;
|
2023-09-15 18:00:27 +02:00
|
|
|
public Map<KeyValue, KeyboardData.PreferredPos> extra_keys_param;
|
|
|
|
public Map<KeyValue, KeyboardData.PreferredPos> extra_keys_custom;
|
2021-04-18 00:55:31 +02:00
|
|
|
|
2021-12-28 17:47:18 +01:00
|
|
|
public final IKeyEventHandler handler;
|
2023-01-15 19:11:08 +01:00
|
|
|
public boolean orientation_landscape = false;
|
2023-11-19 20:10:45 +01:00
|
|
|
/** Index in 'layouts' of the currently used layout. See
|
|
|
|
[get_current_layout()] and [set_current_layout()]. */
|
|
|
|
int current_layout_portrait;
|
|
|
|
int current_layout_landscape;
|
2021-12-28 17:47:18 +01:00
|
|
|
|
2022-11-11 14:27:02 +01:00
|
|
|
private Config(SharedPreferences prefs, Resources res, IKeyEventHandler h)
|
2021-12-19 19:44:27 +01:00
|
|
|
{
|
2022-11-11 14:27:02 +01:00
|
|
|
_prefs = prefs;
|
2021-12-19 19:44:27 +01:00
|
|
|
// static values
|
|
|
|
marginTop = res.getDimension(R.dimen.margin_top);
|
|
|
|
keyPadding = res.getDimension(R.dimen.key_padding);
|
2022-06-06 16:17:43 +02:00
|
|
|
labelTextSize = 0.33f;
|
|
|
|
sublabelTextSize = 0.22f;
|
2024-05-29 11:56:26 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
number_row = KeyboardData.load_number_row(res);
|
|
|
|
bottom_row = KeyboardData.load_bottom_row(res);
|
|
|
|
num_pad = KeyboardData.load_num_pad(res);
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
throw new RuntimeException(e.getMessage()); // Not recoverable
|
|
|
|
}
|
2021-12-19 19:44:27 +01:00
|
|
|
// from prefs
|
2022-11-11 14:27:02 +01:00
|
|
|
refresh(res);
|
2021-04-18 00:55:31 +02:00
|
|
|
// initialized later
|
2023-06-03 18:35:16 +02:00
|
|
|
shouldOfferVoiceTyping = false;
|
2022-01-09 20:26:06 +01:00
|
|
|
actionLabel = null;
|
|
|
|
actionId = 0;
|
2022-01-10 00:27:22 +01:00
|
|
|
swapEnterActionKey = false;
|
2022-09-19 11:41:18 +02:00
|
|
|
extra_keys_subtype = null;
|
2021-12-28 17:47:18 +01:00
|
|
|
handler = h;
|
2021-12-19 19:44:27 +01:00
|
|
|
}
|
2015-10-29 12:49:40 +01:00
|
|
|
|
2021-12-19 19:44:27 +01:00
|
|
|
/*
|
|
|
|
** Reload prefs
|
|
|
|
*/
|
2022-11-11 14:27:02 +01:00
|
|
|
public void refresh(Resources res)
|
2021-12-19 19:44:27 +01:00
|
|
|
{
|
2022-01-30 23:29:50 +01:00
|
|
|
DisplayMetrics dm = res.getDisplayMetrics();
|
2023-01-15 19:11:08 +01:00
|
|
|
orientation_landscape = res.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
|
2022-06-06 15:26:07 +02:00
|
|
|
// The height of the keyboard is relative to the height of the screen.
|
|
|
|
// This is the height of the keyboard if it have 4 rows.
|
2022-02-13 15:58:30 +01:00
|
|
|
int keyboardHeightPercent;
|
2022-06-06 16:17:43 +02:00
|
|
|
float characterSizeScale = 1.f;
|
2022-11-11 14:27:02 +01:00
|
|
|
String show_numpad_s = _prefs.getString("show_numpad", "never");
|
2022-09-25 02:23:33 +02:00
|
|
|
show_numpad = "always".equals(show_numpad_s);
|
2023-01-15 19:11:08 +01:00
|
|
|
if (orientation_landscape)
|
2022-02-13 15:58:30 +01:00
|
|
|
{
|
2022-09-25 02:23:33 +02:00
|
|
|
if ("landscape".equals(show_numpad_s))
|
|
|
|
show_numpad = true;
|
2022-11-11 14:27:02 +01:00
|
|
|
keyboardHeightPercent = _prefs.getInt("keyboard_height_landscape", 50);
|
2022-06-06 16:17:43 +02:00
|
|
|
characterSizeScale = 1.25f;
|
2022-02-13 15:58:30 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-11-11 14:27:02 +01:00
|
|
|
keyboardHeightPercent = _prefs.getInt("keyboard_height", 35);
|
2022-02-13 15:58:30 +01:00
|
|
|
}
|
2023-08-10 12:57:31 +02:00
|
|
|
layouts = LayoutsPreference.load_from_preferences(res, _prefs);
|
2022-12-10 19:39:22 +01:00
|
|
|
inverse_numpad = _prefs.getString("numpad_layout", "default").equals("low_first");
|
2024-05-29 11:56:26 +02:00
|
|
|
add_number_row = _prefs.getBoolean("number_row", false);
|
2022-11-13 14:43:53 +01:00
|
|
|
// The baseline for the swipe distance correspond to approximately the
|
|
|
|
// width of a key in portrait mode, as most layouts have 10 columns.
|
|
|
|
// Multipled by the DPI ratio because most swipes are made in the diagonals.
|
|
|
|
// The option value uses an unnamed scale where the baseline is around 25.
|
|
|
|
float dpi_ratio = Math.max(dm.xdpi, dm.ydpi) / Math.min(dm.xdpi, dm.ydpi);
|
|
|
|
float swipe_scaling = Math.min(dm.widthPixels, dm.heightPixels) / 10.f * dpi_ratio;
|
|
|
|
float swipe_dist_value = Float.valueOf(_prefs.getString("swipe_dist", "15"));
|
|
|
|
swipe_dist_px = swipe_dist_value / 25.f * swipe_scaling;
|
2024-05-02 19:31:48 +02:00
|
|
|
slide_step_px = 0.2f * swipe_scaling;
|
2024-01-09 00:43:28 +01:00
|
|
|
vibrate_custom = _prefs.getBoolean("vibrate_custom", false);
|
|
|
|
vibrate_duration = _prefs.getInt("vibrate_duration", 20);
|
2022-12-31 14:00:38 +01:00
|
|
|
longPressTimeout = _prefs.getInt("longpress_timeout", 600);
|
|
|
|
longPressInterval = _prefs.getInt("longpress_interval", 65);
|
2024-06-30 00:24:39 +02:00
|
|
|
keyrepeat_enabled = _prefs.getBoolean("keyrepeat_enabled", true);
|
2023-06-03 20:20:09 +02:00
|
|
|
margin_bottom = get_dip_pref_oriented(dm, "margin_bottom", 7, 3);
|
2024-01-28 19:38:29 +01:00
|
|
|
key_vertical_margin = get_dip_pref(dm, "key_vertical_margin", 1.5f) / 100;
|
|
|
|
key_horizontal_margin = get_dip_pref(dm, "key_horizontal_margin", 2) / 100;
|
2022-11-11 19:47:37 +01:00
|
|
|
// Label brightness is used as the alpha channel
|
|
|
|
labelBrightness = _prefs.getInt("label_brightness", 100) * 255 / 100;
|
2022-12-11 22:10:00 +01:00
|
|
|
// Keyboard opacity
|
|
|
|
keyboardOpacity = _prefs.getInt("keyboard_opacity", 100) * 255 / 100;
|
|
|
|
keyOpacity = _prefs.getInt("key_opacity", 100) * 255 / 100;
|
|
|
|
keyActivatedOpacity = _prefs.getInt("key_activated_opacity", 100) * 255 / 100;
|
2024-02-10 11:38:46 +01:00
|
|
|
// keyboard border settings
|
|
|
|
borderConfig = _prefs.getBoolean("border_config", false);
|
|
|
|
customBorderRadius = _prefs.getInt("custom_border_radius", 0) / 100.f;
|
|
|
|
customBorderLineWidth = get_dip_pref(dm, "custom_border_line_width", 0);
|
2024-01-28 19:38:29 +01:00
|
|
|
// Do not substract key_vertical_margin from keyHeight because this is done
|
|
|
|
// during rendering.
|
2022-02-13 15:58:30 +01:00
|
|
|
keyHeight = dm.heightPixels * keyboardHeightPercent / 100 / 4;
|
2023-01-15 19:11:08 +01:00
|
|
|
horizontal_margin =
|
2023-06-03 20:20:09 +02:00
|
|
|
get_dip_pref_oriented(dm, "horizontal_margin", 3, 28);
|
2022-11-11 14:27:02 +01:00
|
|
|
double_tap_lock_shift = _prefs.getBoolean("lock_double_tap", false);
|
2022-06-06 16:17:43 +02:00
|
|
|
characterSize =
|
2024-09-21 23:30:01 +02:00
|
|
|
_prefs.getFloat("character_size", 1.15f)
|
2022-06-06 16:17:43 +02:00
|
|
|
* characterSizeScale;
|
2022-11-11 14:27:02 +01:00
|
|
|
theme = getThemeId(res, _prefs.getString("theme", ""));
|
|
|
|
autocapitalisation = _prefs.getBoolean("autocapitalisation", true);
|
2023-02-12 23:20:11 +01:00
|
|
|
switch_input_immediate = _prefs.getBoolean("switch_input_immediate", false);
|
2023-07-09 18:06:12 +02:00
|
|
|
extra_keys_param = ExtraKeysPreference.get_extra_keys(_prefs);
|
2023-07-18 00:31:32 +02:00
|
|
|
extra_keys_custom = CustomExtraKeysPreference.get(_prefs);
|
2023-07-29 17:29:45 +02:00
|
|
|
pin_entry_enabled = _prefs.getBoolean("pin_entry_enabled", true);
|
2023-11-19 20:10:45 +01:00
|
|
|
current_layout_portrait = _prefs.getInt("current_layout_portrait", 0);
|
|
|
|
current_layout_landscape = _prefs.getInt("current_layout_landscape", 0);
|
2024-06-09 14:25:19 +02:00
|
|
|
circle_sensitivity = Integer.valueOf(_prefs.getString("circle_sensitivity", "2"));
|
2024-07-06 22:16:37 +02:00
|
|
|
clipboard_history_enabled = _prefs.getBoolean("clipboard_history_enabled", false);
|
2023-11-19 20:10:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public int get_current_layout()
|
|
|
|
{
|
|
|
|
return (orientation_landscape)
|
|
|
|
? current_layout_landscape : current_layout_portrait;
|
2023-11-19 19:07:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public void set_current_layout(int l)
|
|
|
|
{
|
2023-11-19 20:10:45 +01:00
|
|
|
if (orientation_landscape)
|
|
|
|
current_layout_landscape = l;
|
|
|
|
else
|
|
|
|
current_layout_portrait = l;
|
2023-11-19 19:07:54 +01:00
|
|
|
SharedPreferences.Editor e = _prefs.edit();
|
2023-11-19 20:10:45 +01:00
|
|
|
e.putInt("current_layout_portrait", current_layout_portrait);
|
|
|
|
e.putInt("current_layout_landscape", current_layout_landscape);
|
2023-11-19 19:07:54 +01:00
|
|
|
e.apply();
|
2021-12-19 19:44:27 +01:00
|
|
|
}
|
2015-10-29 12:49:40 +01:00
|
|
|
|
2023-01-30 23:46:02 +01:00
|
|
|
KeyValue action_key()
|
|
|
|
{
|
|
|
|
// Update the name to avoid caching in KeyModifier
|
|
|
|
return (actionLabel == null) ? null :
|
|
|
|
KeyValue.getKeyByName("action").withSymbol(actionLabel);
|
|
|
|
}
|
|
|
|
|
2022-03-05 18:15:36 +01:00
|
|
|
/** Update the layout according to the configuration.
|
|
|
|
* - Remove the switching key if it isn't needed
|
2022-05-29 12:27:46 +02:00
|
|
|
* - Remove "localized" keys from other locales (not in 'extra_keys')
|
2022-03-05 18:15:36 +01:00
|
|
|
* - Replace the action key to show the right label
|
|
|
|
* - Swap the enter and action keys
|
2023-01-30 23:58:47 +01:00
|
|
|
* - Add the optional numpad and number row
|
2023-07-18 00:31:32 +02:00
|
|
|
* - Add the extra keys
|
2022-03-05 18:15:36 +01:00
|
|
|
*/
|
2022-12-10 19:39:22 +01:00
|
|
|
public KeyboardData modify_layout(KeyboardData kw)
|
2022-03-05 18:15:36 +01:00
|
|
|
{
|
2023-01-30 23:46:02 +01:00
|
|
|
final KeyValue action_key = action_key();
|
2022-05-29 12:27:46 +02:00
|
|
|
// Extra keys are removed from the set as they are encountered during the
|
|
|
|
// first iteration then automatically added.
|
2023-09-15 18:00:27 +02:00
|
|
|
final Map<KeyValue, KeyboardData.PreferredPos> extra_keys = new HashMap<KeyValue, KeyboardData.PreferredPos>();
|
2023-01-30 23:54:39 +01:00
|
|
|
final Set<KeyValue> remove_keys = new HashSet<KeyValue>();
|
2024-02-22 19:10:31 +01:00
|
|
|
// Make sure the config key is accessible to avoid being locked in a custom
|
|
|
|
// layout.
|
|
|
|
extra_keys.put(KeyValue.getKeyByName("config"), KeyboardData.PreferredPos.ANYWHERE);
|
2023-09-15 18:00:27 +02:00
|
|
|
extra_keys.putAll(extra_keys_param);
|
|
|
|
extra_keys.putAll(extra_keys_custom);
|
2024-07-06 23:09:51 +02:00
|
|
|
if (extra_keys_subtype != null && kw.locale_extra_keys)
|
2023-08-06 01:30:02 +02:00
|
|
|
{
|
|
|
|
Set<KeyValue> present = new HashSet<KeyValue>();
|
2023-09-10 11:43:56 +02:00
|
|
|
present.addAll(kw.getKeys().keySet());
|
2023-09-15 18:00:27 +02:00
|
|
|
present.addAll(extra_keys_param.keySet());
|
|
|
|
present.addAll(extra_keys_custom.keySet());
|
2023-08-06 01:30:02 +02:00
|
|
|
extra_keys_subtype.compute(extra_keys,
|
|
|
|
new ExtraKeys.Query(kw.script, present));
|
|
|
|
}
|
2024-05-29 11:56:26 +02:00
|
|
|
KeyboardData.Row added_number_row = null;
|
|
|
|
if (add_number_row && !show_numpad)
|
|
|
|
added_number_row = modify_number_row(number_row, kw);
|
|
|
|
if (added_number_row != null)
|
|
|
|
remove_keys.addAll(added_number_row.getKeys(0).keySet());
|
|
|
|
if (kw.bottom_row)
|
|
|
|
kw = kw.insert_row(bottom_row, kw.rows.size());
|
2022-12-10 19:39:22 +01:00
|
|
|
kw = kw.mapKeys(new KeyboardData.MapKeyValues() {
|
2022-06-24 20:26:27 +02:00
|
|
|
public KeyValue apply(KeyValue key, boolean localized)
|
2022-03-05 18:15:36 +01:00
|
|
|
{
|
2023-09-15 18:00:27 +02:00
|
|
|
boolean is_extra_key = extra_keys.containsKey(key);
|
2022-05-29 12:27:46 +02:00
|
|
|
if (is_extra_key)
|
2022-06-06 00:23:45 +02:00
|
|
|
extra_keys.remove(key);
|
2022-06-24 20:26:27 +02:00
|
|
|
if (localized && !is_extra_key)
|
2022-06-05 17:26:34 +02:00
|
|
|
return null;
|
2023-01-30 23:54:39 +01:00
|
|
|
if (remove_keys.contains(key))
|
|
|
|
return null;
|
2022-06-05 17:26:34 +02:00
|
|
|
switch (key.getKind())
|
2022-04-16 23:36:54 +02:00
|
|
|
{
|
2022-06-05 17:26:34 +02:00
|
|
|
case Event:
|
|
|
|
switch (key.getEvent())
|
2022-04-16 23:36:54 +02:00
|
|
|
{
|
2024-01-15 22:09:15 +01:00
|
|
|
case CHANGE_METHOD_PICKER:
|
2023-02-12 23:20:11 +01:00
|
|
|
if (switch_input_immediate)
|
|
|
|
return KeyValue.getKeyByName("change_method_prev");
|
|
|
|
return key;
|
2022-06-05 19:30:53 +02:00
|
|
|
case ACTION:
|
2022-06-05 17:26:34 +02:00
|
|
|
return (swapEnterActionKey && action_key != null) ?
|
|
|
|
KeyValue.getKeyByName("enter") : action_key;
|
2023-07-29 18:37:06 +02:00
|
|
|
case SWITCH_FORWARD:
|
|
|
|
return (layouts.size() > 1) ? key : null;
|
|
|
|
case SWITCH_BACKWARD:
|
|
|
|
return (layouts.size() > 2) ? key : null;
|
2023-06-03 18:35:16 +02:00
|
|
|
case SWITCH_VOICE_TYPING:
|
2023-12-30 01:24:21 +01:00
|
|
|
case SWITCH_VOICE_TYPING_CHOOSER:
|
2023-06-03 18:35:16 +02:00
|
|
|
return shouldOfferVoiceTyping ? key : null;
|
2022-04-16 23:36:54 +02:00
|
|
|
}
|
2022-06-05 19:30:53 +02:00
|
|
|
break;
|
|
|
|
case Keyevent:
|
|
|
|
switch (key.getKeyevent())
|
|
|
|
{
|
|
|
|
case KeyEvent.KEYCODE_ENTER:
|
|
|
|
return (swapEnterActionKey && action_key != null) ? action_key : key;
|
|
|
|
}
|
2022-06-05 17:26:34 +02:00
|
|
|
break;
|
|
|
|
case Modifier:
|
2022-11-06 19:34:57 +01:00
|
|
|
switch (key.getModifier())
|
|
|
|
{
|
|
|
|
case SHIFT:
|
|
|
|
if (double_tap_lock_shift)
|
|
|
|
return key.withFlags(key.getFlags() | KeyValue.FLAG_LOCK);
|
|
|
|
}
|
2022-06-05 17:26:34 +02:00
|
|
|
break;
|
2022-04-16 23:36:54 +02:00
|
|
|
}
|
2022-06-05 17:26:34 +02:00
|
|
|
return key;
|
2022-04-16 23:36:54 +02:00
|
|
|
}
|
|
|
|
});
|
2023-01-30 23:54:39 +01:00
|
|
|
if (show_numpad)
|
2024-05-29 11:56:26 +02:00
|
|
|
kw = kw.addNumPad(modify_numpad(num_pad, kw));
|
|
|
|
if (added_number_row != null)
|
|
|
|
kw = kw.insert_row(added_number_row, 0);
|
2022-05-29 12:27:46 +02:00
|
|
|
if (extra_keys.size() > 0)
|
2023-09-15 18:00:27 +02:00
|
|
|
kw = kw.addExtraKeys(extra_keys.entrySet().iterator());
|
2022-05-29 12:27:46 +02:00
|
|
|
return kw;
|
2022-03-05 18:15:36 +01:00
|
|
|
}
|
|
|
|
|
2023-12-26 17:05:51 +01:00
|
|
|
/** Handle the numpad layout. The [main_kw] is used to adapt the numpad to
|
|
|
|
the main layout's script. */
|
|
|
|
public KeyboardData modify_numpad(KeyboardData kw, KeyboardData main_kw)
|
2023-01-30 23:46:02 +01:00
|
|
|
{
|
|
|
|
final KeyValue action_key = action_key();
|
2023-12-26 17:05:51 +01:00
|
|
|
final KeyModifier.Map_char map_digit = KeyModifier.modify_numpad_script(main_kw.numpad_script);
|
2023-01-30 23:46:02 +01:00
|
|
|
return kw.mapKeys(new KeyboardData.MapKeyValues() {
|
|
|
|
public KeyValue apply(KeyValue key, boolean localized)
|
|
|
|
{
|
|
|
|
switch (key.getKind())
|
|
|
|
{
|
|
|
|
case Event:
|
|
|
|
switch (key.getEvent())
|
|
|
|
{
|
|
|
|
case ACTION:
|
|
|
|
return (swapEnterActionKey && action_key != null) ?
|
|
|
|
KeyValue.getKeyByName("enter") : action_key;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Keyevent:
|
|
|
|
switch (key.getKeyevent())
|
|
|
|
{
|
|
|
|
case KeyEvent.KEYCODE_ENTER:
|
|
|
|
return (swapEnterActionKey && action_key != null) ? action_key : key;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Char:
|
2023-09-03 23:38:55 +02:00
|
|
|
char prev_c = key.getChar();
|
|
|
|
char c = prev_c;
|
2023-01-30 23:46:02 +01:00
|
|
|
if (inverse_numpad)
|
2023-09-03 23:38:55 +02:00
|
|
|
c = inverse_numpad_char(c);
|
|
|
|
String modified = map_digit.apply(c);
|
|
|
|
if (modified != null) // Was modified by script
|
2024-02-28 20:42:52 +01:00
|
|
|
return KeyValue.makeStringKey(modified);
|
2023-09-03 23:38:55 +02:00
|
|
|
if (prev_c != c) // Was inverted
|
|
|
|
return key.withChar(c);
|
2023-01-30 23:46:02 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return key;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-02-28 23:19:50 +01:00
|
|
|
static KeyboardData.MapKeyValues numpad_script_map(String numpad_script)
|
2024-02-14 22:41:35 +01:00
|
|
|
{
|
2024-02-28 23:19:50 +01:00
|
|
|
final KeyModifier.Map_char map_digit = KeyModifier.modify_numpad_script(numpad_script);
|
|
|
|
return new KeyboardData.MapKeyValues() {
|
2024-02-14 22:41:35 +01:00
|
|
|
public KeyValue apply(KeyValue key, boolean localized)
|
|
|
|
{
|
|
|
|
switch (key.getKind())
|
|
|
|
{
|
|
|
|
case Char:
|
|
|
|
String modified = map_digit.apply(key.getChar());
|
|
|
|
if (modified != null)
|
2024-02-28 20:42:52 +01:00
|
|
|
return KeyValue.makeStringKey(modified);
|
2024-02-14 22:41:35 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return key;
|
|
|
|
}
|
2024-02-28 23:19:50 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Modify the pin entry layout. [main_kw] is used to map the digits into the
|
|
|
|
same script. */
|
|
|
|
public KeyboardData modify_pinentry(KeyboardData kw, KeyboardData main_kw)
|
|
|
|
{
|
|
|
|
return kw.mapKeys(numpad_script_map(main_kw.numpad_script));
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Modify the number row according to [main_kw]'s script. */
|
|
|
|
public KeyboardData.Row modify_number_row(KeyboardData.Row row,
|
|
|
|
KeyboardData main_kw)
|
|
|
|
{
|
|
|
|
return row.mapKeys(numpad_script_map(main_kw.numpad_script));
|
2024-02-14 22:41:35 +01:00
|
|
|
}
|
|
|
|
|
2023-01-15 19:11:08 +01:00
|
|
|
private float get_dip_pref(DisplayMetrics dm, String pref_name, float def)
|
2021-12-19 19:44:27 +01:00
|
|
|
{
|
2022-01-30 23:55:15 +01:00
|
|
|
float value;
|
2023-01-15 19:11:08 +01:00
|
|
|
try { value = _prefs.getInt(pref_name, -1); }
|
|
|
|
catch (Exception e) { value = _prefs.getFloat(pref_name, -1f); }
|
2022-01-30 23:55:15 +01:00
|
|
|
if (value < 0f)
|
2023-08-16 18:18:38 +02:00
|
|
|
value = def;
|
2021-12-28 16:47:19 +01:00
|
|
|
return (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, dm));
|
2021-12-19 19:44:27 +01:00
|
|
|
}
|
2021-04-28 00:23:52 +02:00
|
|
|
|
2023-06-03 20:20:09 +02:00
|
|
|
/** [get_dip_pref] depending on orientation. */
|
|
|
|
float get_dip_pref_oriented(DisplayMetrics dm, String pref_base_name, float def_port, float def_land)
|
2023-01-15 19:11:08 +01:00
|
|
|
{
|
|
|
|
String suffix = orientation_landscape ? "_landscape" : "_portrait";
|
2023-06-03 20:20:09 +02:00
|
|
|
float def = orientation_landscape ? def_land : def_port;
|
|
|
|
return get_dip_pref(dm, pref_base_name + suffix, def);
|
2023-01-15 19:11:08 +01:00
|
|
|
}
|
|
|
|
|
2022-01-30 23:29:50 +01:00
|
|
|
private int getThemeId(Resources res, String theme_name)
|
|
|
|
{
|
2024-07-06 22:32:01 +02:00
|
|
|
int night_mode = res.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
|
2022-01-30 23:29:50 +01:00
|
|
|
switch (theme_name)
|
|
|
|
{
|
|
|
|
case "light": return R.style.Light;
|
|
|
|
case "black": return R.style.Black;
|
2023-02-26 09:47:31 +01:00
|
|
|
case "altblack": return R.style.AltBlack;
|
2022-01-30 23:29:50 +01:00
|
|
|
case "dark": return R.style.Dark;
|
2022-09-24 13:13:51 +02:00
|
|
|
case "white": return R.style.White;
|
2023-01-31 20:11:36 +01:00
|
|
|
case "epaper": return R.style.ePaper;
|
2023-11-03 02:07:58 +01:00
|
|
|
case "desert": return R.style.Desert;
|
|
|
|
case "jungle": return R.style.Jungle;
|
2024-07-06 22:32:01 +02:00
|
|
|
case "monetlight": return R.style.MonetLight;
|
|
|
|
case "monetdark": return R.style.MonetDark;
|
|
|
|
case "monet":
|
|
|
|
if ((night_mode & Configuration.UI_MODE_NIGHT_NO) != 0)
|
|
|
|
return R.style.MonetLight;
|
|
|
|
return R.style.MonetDark;
|
2022-01-30 23:29:50 +01:00
|
|
|
default:
|
|
|
|
case "system":
|
2024-02-10 17:24:15 +01:00
|
|
|
if ((night_mode & Configuration.UI_MODE_NIGHT_NO) != 0)
|
|
|
|
return R.style.Light;
|
2022-01-30 23:29:50 +01:00
|
|
|
return R.style.Dark;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-10 19:39:22 +01:00
|
|
|
char inverse_numpad_char(char c)
|
|
|
|
{
|
|
|
|
switch (c)
|
|
|
|
{
|
|
|
|
case '7': return '1';
|
|
|
|
case '8': return '2';
|
|
|
|
case '9': return '3';
|
|
|
|
case '1': return '7';
|
|
|
|
case '2': return '8';
|
|
|
|
case '3': return '9';
|
|
|
|
default: return c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-28 16:47:19 +01:00
|
|
|
private static Config _globalConfig = null;
|
|
|
|
|
2022-11-11 14:27:02 +01:00
|
|
|
public static void initGlobalConfig(SharedPreferences prefs, Resources res,
|
|
|
|
IKeyEventHandler handler)
|
2021-12-28 16:47:19 +01:00
|
|
|
{
|
2023-08-15 20:23:33 +02:00
|
|
|
migrate(prefs);
|
2022-11-11 14:27:02 +01:00
|
|
|
_globalConfig = new Config(prefs, res, handler);
|
2021-12-28 16:47:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public static Config globalConfig()
|
|
|
|
{
|
|
|
|
return _globalConfig;
|
|
|
|
}
|
2021-12-28 17:47:18 +01:00
|
|
|
|
2023-12-30 00:56:55 +01:00
|
|
|
public static SharedPreferences globalPrefs()
|
|
|
|
{
|
|
|
|
return _globalConfig._prefs;
|
|
|
|
}
|
|
|
|
|
2021-12-28 17:47:18 +01:00
|
|
|
public static interface IKeyEventHandler
|
|
|
|
{
|
2023-08-26 23:37:22 +02:00
|
|
|
public void key_down(KeyValue value, boolean is_swipe);
|
2024-01-26 00:17:51 +01:00
|
|
|
public void key_up(KeyValue value, Pointers.Modifiers mods);
|
|
|
|
public void mods_changed(Pointers.Modifiers mods);
|
2021-12-28 17:47:18 +01:00
|
|
|
}
|
2023-08-15 20:23:33 +02:00
|
|
|
|
|
|
|
/** Config migrations. */
|
|
|
|
|
|
|
|
private static int CONFIG_VERSION = 1;
|
|
|
|
|
|
|
|
public static void migrate(SharedPreferences prefs)
|
|
|
|
{
|
|
|
|
int saved_version = prefs.getInt("version", 0);
|
|
|
|
Logs.debug_config_migration(saved_version, CONFIG_VERSION);
|
|
|
|
if (saved_version == CONFIG_VERSION)
|
|
|
|
return;
|
|
|
|
SharedPreferences.Editor e = prefs.edit();
|
|
|
|
e.putInt("version", CONFIG_VERSION);
|
|
|
|
// Migrations might run on an empty [prefs] for new installs, in this case
|
|
|
|
// they set the default values of complex options.
|
|
|
|
switch (saved_version) // Fallback switch
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
// Primary, secondary and custom layout options are merged into the new
|
|
|
|
// Layouts option. This also sets the default value.
|
|
|
|
List<LayoutsPreference.Layout> l = new ArrayList<LayoutsPreference.Layout>();
|
|
|
|
l.add(migrate_layout(prefs.getString("layout", "system")));
|
|
|
|
String snd_layout = prefs.getString("second_layout", "none");
|
|
|
|
if (snd_layout != null && !snd_layout.equals("none"))
|
|
|
|
l.add(migrate_layout(snd_layout));
|
|
|
|
String custom_layout = prefs.getString("custom_layout", "");
|
|
|
|
if (custom_layout != null && !custom_layout.equals(""))
|
2024-01-10 23:39:19 +01:00
|
|
|
l.add(LayoutsPreference.CustomLayout.parse(custom_layout));
|
2023-08-15 20:23:33 +02:00
|
|
|
LayoutsPreference.save_to_preferences(e, l);
|
|
|
|
case 1:
|
|
|
|
default: break;
|
|
|
|
}
|
2024-02-10 18:03:09 +01:00
|
|
|
e.apply();
|
2023-08-15 20:23:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private static LayoutsPreference.Layout migrate_layout(String name)
|
|
|
|
{
|
|
|
|
if (name == null || name.equals("system"))
|
|
|
|
return new LayoutsPreference.SystemLayout();
|
|
|
|
return new LayoutsPreference.NamedLayout(name);
|
|
|
|
}
|
2015-10-29 12:49:40 +01:00
|
|
|
}
|