Unexpected-Keyboard/srcs/juloo.keyboard2/Keyboard2.java

295 lines
8.7 KiB
Java
Raw Normal View History

2015-07-30 20:14:55 +02:00
package juloo.keyboard2;
import android.content.Context;
2015-08-08 17:57:25 +02:00
import android.content.Intent;
2015-08-08 16:47:22 +02:00
import android.content.SharedPreferences;
2015-07-30 20:14:55 +02:00
import android.inputmethodservice.InputMethodService;
import android.os.Build.VERSION;
import android.os.IBinder;
2015-08-08 16:47:22 +02:00
import android.preference.PreferenceManager;
import android.text.InputType;
import android.view.ContextThemeWrapper;
2015-10-11 15:30:39 +02:00
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodInfo;
2016-12-11 22:45:58 +01:00
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
import android.view.KeyEvent;
2015-07-30 20:14:55 +02:00
import android.view.View;
import android.view.ViewGroup;
2022-01-20 21:22:09 +01:00
import android.view.ViewParent;
import java.util.List;
2015-07-30 20:14:55 +02:00
public class Keyboard2 extends InputMethodService
implements SharedPreferences.OnSharedPreferenceChangeListener
2015-07-30 20:14:55 +02:00
{
private Keyboard2View _keyboardView;
private int _currentTextLayout;
private ViewGroup _emojiPane = null;
2015-07-30 20:14:55 +02:00
private Config _config;
2015-10-29 12:49:40 +01:00
private KeyboardData getLayout(int resId)
{
return KeyboardData.load(getResources(), resId);
}
@Override
public void onCreate()
{
super.onCreate();
PreferenceManager.setDefaultValues(this, R.xml.settings, false);
PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
Config.initGlobalConfig(this, new KeyEventHandler(this.new Receiver()));
_config = Config.globalConfig();
_config.refresh(this);
_keyboardView = (Keyboard2View)inflate_view(R.layout.keyboard);
_keyboardView.reset();
}
2015-10-29 12:49:40 +01:00
private List<InputMethodSubtype> getEnabledSubtypes(InputMethodManager imm)
{
String pkg = getPackageName();
for (InputMethodInfo imi : imm.getEnabledInputMethodList())
if (imi.getPackageName().equals(pkg))
return imm.getEnabledInputMethodSubtypeList(imi, true);
return null;
}
private void refreshSubtypeLayout(InputMethodSubtype subtype)
{
int l = _config.layout;
if (l == -1)
{
String s = subtype.getExtraValueOf("default_layout");
if (s != null)
l = Config.layoutId_of_string(s);
}
_currentTextLayout = l;
}
private int extra_keys_of_subtype(InputMethodSubtype subtype)
{
String extra_keys = subtype.getExtraValueOf("extra_keys");
int flags = 0;
if (extra_keys != null)
for (String acc : extra_keys.split("\\|"))
flags |= Config.extra_key_flag_of_name(acc);
return flags;
}
private void refreshAccentsOption(InputMethodManager imm, InputMethodSubtype subtype)
{
int to_keep = 0;
switch (_config.accents)
{
case 1:
to_keep |= extra_keys_of_subtype(subtype);
for (InputMethodSubtype s : getEnabledSubtypes(imm))
to_keep |= extra_keys_of_subtype(s);
break;
case 2: to_keep |= extra_keys_of_subtype(subtype); break;
case 3: to_keep = KeyValue.FLAGS_HIDDEN_KEYS; break;
case 4: break;
default: throw new IllegalArgumentException();
}
_config.key_flags_to_remove = ~to_keep & KeyValue.FLAGS_HIDDEN_KEYS;
}
private void refreshSubtypeLegacyFallback()
{
// Fallback for the accents option: Only respect the "None" case
switch (_config.accents)
{
case 1: case 2: case 3: _config.key_flags_to_remove = 0; break;
case 4: _config.key_flags_to_remove = KeyValue.FLAGS_HIDDEN_KEYS; break;
}
// Fallback for the layout option: Use qwerty in the "system settings" case
_currentTextLayout = (_config.layout == -1) ? R.xml.qwerty : _config.layout;
}
private void refreshSubtypeImm()
{
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
_config.shouldOfferSwitchingToNextInputMethod = imm.shouldOfferSwitchingToNextInputMethod(getConnectionToken());
if (VERSION.SDK_INT < 12)
{
// Subtypes won't work well under API level 12 (getExtraValueOf)
refreshSubtypeLegacyFallback();
}
else
{
InputMethodSubtype subtype = imm.getCurrentInputMethodSubtype();
refreshSubtypeLayout(subtype);
refreshAccentsOption(imm, subtype);
}
}
private String actionLabel_of_imeAction(int action)
{
2022-01-23 19:19:38 +01:00
int res;
switch (action)
{
2022-01-23 19:19:38 +01:00
case EditorInfo.IME_ACTION_NEXT: res = R.string.key_action_next; break;
case EditorInfo.IME_ACTION_DONE: res = R.string.key_action_done; break;
case EditorInfo.IME_ACTION_GO: res = R.string.key_action_go; break;
case EditorInfo.IME_ACTION_PREVIOUS: res = R.string.key_action_prev; break;
case EditorInfo.IME_ACTION_SEARCH: res = R.string.key_action_search; break;
case EditorInfo.IME_ACTION_SEND: res = R.string.key_action_send; break;
case EditorInfo.IME_ACTION_UNSPECIFIED:
case EditorInfo.IME_ACTION_NONE:
default: return null;
}
2022-01-23 19:19:38 +01:00
return getResources().getString(res);
}
private void refreshEditorInfo(EditorInfo info)
{
// First try to look at 'info.actionLabel', if it isn't set, look at
// 'imeOptions'.
if (info.actionLabel != null)
{
_config.actionLabel = info.actionLabel.toString();
_config.actionId = info.actionId;
_config.swapEnterActionKey = false;
}
else
{
int action = info.imeOptions & EditorInfo.IME_MASK_ACTION;
_config.actionLabel = actionLabel_of_imeAction(action); // Might be null
_config.actionId = action;
_config.swapEnterActionKey =
(info.imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) == 0;
}
}
private void refreshConfig()
{
int prev_theme = _config.theme;
_config.refresh(this);
refreshSubtypeImm();
// Refreshing the theme config requires re-creating the views
if (prev_theme != _config.theme)
{
_keyboardView = (Keyboard2View)inflate_view(R.layout.keyboard);
_emojiPane = null;
}
_keyboardView.setKeyboard(getLayout(_currentTextLayout));
}
@Override
public void onStartInputView(EditorInfo info, boolean restarting)
{
refreshConfig();
refreshEditorInfo(info);
if ((info.inputType & InputType.TYPE_CLASS_NUMBER) != 0)
_keyboardView.setKeyboard(getLayout(R.xml.numeric));
setInputView(_keyboardView);
}
2015-10-11 15:30:39 +02:00
2022-01-20 21:22:09 +01:00
@Override
public void setInputView(View v)
{
ViewParent parent = v.getParent();
if (parent != null && parent instanceof ViewGroup)
((ViewGroup)parent).removeView(v);
super.setInputView(v);
}
@Override
public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype)
{
refreshSubtypeImm();
_keyboardView.setKeyboard(getLayout(_currentTextLayout));
}
@Override
public void onFinishInputView(boolean finishingInput)
{
super.onFinishInputView(finishingInput);
_keyboardView.reset();
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
refreshConfig();
}
2015-10-01 17:11:52 +02:00
/** Not static */
public class Receiver implements KeyEventHandler.IReceiver
{
public void switchToNextInputMethod()
{
InputMethodManager imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
imm.showInputMethodPicker();
// deprecated in version 28: imm.switchToNextInputMethod(getConnectionToken(), false);
// added in version 28: switchToNextInputMethod(false);
}
public void setPane_emoji()
{
if (_emojiPane == null)
_emojiPane = (ViewGroup)inflate_view(R.layout.emoji_pane);
setInputView(_emojiPane);
}
public void setPane_normal()
{
setInputView(_keyboardView);
}
public void performAction()
{
InputConnection conn = getCurrentInputConnection();
if (conn == null)
return;
conn.performEditorAction(_config.actionId);
}
public void setLayout(int res_id)
{
if (res_id == -1)
res_id = _currentTextLayout;
_keyboardView.setKeyboard(getLayout(res_id));
}
2015-08-03 15:58:13 +02:00
public void sendKeyEvent(int eventCode, int meta)
{
InputConnection conn = getCurrentInputConnection();
if (conn == null)
return;
KeyEvent event = new KeyEvent(1, 1, KeyEvent.ACTION_DOWN, eventCode, 0, meta);
conn.sendKeyEvent(event);
conn.sendKeyEvent(KeyEvent.changeAction(event, KeyEvent.ACTION_UP));
}
2015-08-03 15:58:13 +02:00
public void showKeyboardConfig()
{
Intent intent = new Intent(Keyboard2.this, SettingsActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
2015-08-03 15:58:13 +02:00
public void commitText(String text)
{
getCurrentInputConnection().commitText(text, 1);
}
2015-08-03 15:58:13 +02:00
public void commitChar(char c)
{
sendKeyChar(c);
}
}
private IBinder getConnectionToken()
{
return getWindow().getWindow().getAttributes().token;
}
private View inflate_view(int layout)
{
return View.inflate(new ContextThemeWrapper(this, _config.theme), layout, null);
}
2015-07-30 20:14:55 +02:00
}