2021-12-28 17:47:18 +01:00
|
|
|
package juloo.keyboard2;
|
|
|
|
|
2022-11-13 16:18:08 +01:00
|
|
|
import android.os.Looper;
|
2021-12-28 17:47:18 +01:00
|
|
|
import android.view.KeyEvent;
|
2022-11-13 16:18:08 +01:00
|
|
|
import android.view.inputmethod.EditorInfo;
|
|
|
|
import android.view.inputmethod.InputConnection;
|
2021-12-28 17:47:18 +01:00
|
|
|
|
|
|
|
class KeyEventHandler implements Config.IKeyEventHandler
|
|
|
|
{
|
2022-11-13 16:18:08 +01:00
|
|
|
IReceiver _recv;
|
|
|
|
Autocapitalisation _autocap;
|
2021-12-28 17:47:18 +01:00
|
|
|
|
2022-11-13 16:18:08 +01:00
|
|
|
public int actionId; // Action performed by the Action key.
|
|
|
|
|
|
|
|
public KeyEventHandler(Looper looper, IReceiver recv)
|
2021-12-28 17:47:18 +01:00
|
|
|
{
|
|
|
|
_recv = recv;
|
2022-11-13 16:18:08 +01:00
|
|
|
_autocap = new Autocapitalisation(looper,
|
|
|
|
this.new Autocapitalisation_callback());
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Editing just started. */
|
|
|
|
public void started(EditorInfo info)
|
|
|
|
{
|
|
|
|
_autocap.started(info, _recv.getCurrentInputConnection());
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Selection has been updated. */
|
|
|
|
public void selection_updated(int oldSelStart, int newSelStart)
|
|
|
|
{
|
|
|
|
_autocap.selection_updated(oldSelStart, newSelStart);
|
2021-12-28 17:47:18 +01:00
|
|
|
}
|
|
|
|
|
2022-11-13 16:18:08 +01:00
|
|
|
/** A key has been released. */
|
|
|
|
public void key_up(KeyValue key, Pointers.Modifiers mods)
|
2021-12-28 17:47:18 +01:00
|
|
|
{
|
2022-06-05 17:26:34 +02:00
|
|
|
if (key == null)
|
2022-03-13 00:35:15 +01:00
|
|
|
return;
|
2022-06-05 17:26:34 +02:00
|
|
|
switch (key.getKind())
|
2021-12-28 17:47:18 +01:00
|
|
|
{
|
2022-11-13 16:18:08 +01:00
|
|
|
case Char: send_text(String.valueOf(key.getChar())); break;
|
|
|
|
case String: send_text(key.getString()); break;
|
2022-06-05 17:26:34 +02:00
|
|
|
case Event:
|
2022-06-05 19:30:53 +02:00
|
|
|
switch (key.getEvent())
|
2022-06-05 17:26:34 +02:00
|
|
|
{
|
2022-06-05 19:30:53 +02:00
|
|
|
case CONFIG: _recv.showKeyboardConfig(); break;
|
2022-11-13 00:24:23 +01:00
|
|
|
case SWITCH_TEXT:
|
2022-12-29 12:43:02 +01:00
|
|
|
case SWITCH_SECOND_BACK: _recv.switch_text(); break;
|
2022-11-13 16:18:08 +01:00
|
|
|
case SWITCH_NUMERIC: _recv.switch_layout(R.xml.numeric); break;
|
2022-06-05 19:30:53 +02:00
|
|
|
case SWITCH_EMOJI: _recv.setPane_emoji(); break;
|
|
|
|
case SWITCH_BACK_EMOJI: _recv.setPane_normal(); break;
|
|
|
|
case CHANGE_METHOD: _recv.switchToNextInputMethod(); break;
|
2022-11-13 16:18:08 +01:00
|
|
|
case ACTION:
|
|
|
|
InputConnection conn = _recv.getCurrentInputConnection();
|
|
|
|
if (conn != null)
|
|
|
|
conn.performEditorAction(actionId);
|
|
|
|
break;
|
|
|
|
case SWITCH_SECOND: _recv.switch_second(); break;
|
|
|
|
case SWITCH_GREEKMATH: _recv.switch_layout(R.xml.greekmath); break;
|
|
|
|
case CAPS_LOCK: _recv.set_shift_state(true, true); break;
|
2022-06-05 17:26:34 +02:00
|
|
|
}
|
|
|
|
break;
|
2022-06-05 19:30:53 +02:00
|
|
|
case Keyevent:
|
|
|
|
handleKeyUpWithModifier(key.getKeyevent(), mods);
|
|
|
|
break;
|
2022-06-05 17:26:34 +02:00
|
|
|
case Modifier:
|
|
|
|
break;
|
2022-11-13 16:45:57 +01:00
|
|
|
case Editing:
|
2022-12-30 15:15:58 +01:00
|
|
|
send_context_menu_action(action_of_editing_key(key.getEditing()));
|
2022-11-13 16:45:57 +01:00
|
|
|
break;
|
2021-12-28 17:47:18 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-30 15:15:58 +01:00
|
|
|
static int action_of_editing_key(KeyValue.Editing e)
|
|
|
|
{
|
|
|
|
switch (e)
|
|
|
|
{
|
|
|
|
case COPY: return android.R.id.copy;
|
|
|
|
case PASTE: return android.R.id.paste;
|
|
|
|
case CUT: return android.R.id.cut;
|
|
|
|
case SELECT_ALL: return android.R.id.selectAll;
|
|
|
|
case SHARE: return android.R.id.shareText;
|
|
|
|
case PASTE_PLAIN: return android.R.id.pasteAsPlainText;
|
|
|
|
case UNDO: return android.R.id.undo;
|
|
|
|
case REDO: return android.R.id.redo;
|
|
|
|
case REPLACE: return android.R.id.replaceText;
|
|
|
|
case ASSIST: return android.R.id.textAssist;
|
|
|
|
case AUTOFILL: return android.R.id.autofill;
|
|
|
|
default: return -1; // sad
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-28 17:47:18 +01:00
|
|
|
// private void handleDelKey(int before, int after)
|
|
|
|
// {
|
|
|
|
// CharSequence selection = getCurrentInputConnection().getSelectedText(0);
|
|
|
|
|
|
|
|
// if (selection != null && selection.length() > 0)
|
|
|
|
// getCurrentInputConnection().commitText("", 1);
|
|
|
|
// else
|
|
|
|
// getCurrentInputConnection().deleteSurroundingText(before, after);
|
|
|
|
// }
|
|
|
|
|
2022-11-13 16:18:08 +01:00
|
|
|
int sendMetaKey(int eventCode, int metaFlags, int metaState, boolean down)
|
2021-12-28 17:47:18 +01:00
|
|
|
{
|
2022-02-22 19:32:16 +01:00
|
|
|
int action;
|
|
|
|
int updatedMetaState;
|
|
|
|
if (down) { action = KeyEvent.ACTION_DOWN; updatedMetaState = metaState | metaFlags; }
|
|
|
|
else { action = KeyEvent.ACTION_UP; updatedMetaState = metaState & ~metaFlags; }
|
2022-11-13 16:18:08 +01:00
|
|
|
send_keyevent(action, eventCode, metaState);
|
2022-02-22 19:32:16 +01:00
|
|
|
return updatedMetaState;
|
|
|
|
}
|
|
|
|
|
2022-11-13 16:18:08 +01:00
|
|
|
int sendMetaKeyForModifier(KeyValue.Modifier mod, int metaState, boolean down)
|
2022-02-22 19:32:16 +01:00
|
|
|
{
|
2022-06-05 01:38:42 +02:00
|
|
|
switch (mod)
|
|
|
|
{
|
2022-06-05 19:30:53 +02:00
|
|
|
case CTRL:
|
2022-06-05 01:38:42 +02:00
|
|
|
return sendMetaKey(KeyEvent.KEYCODE_CTRL_LEFT, KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_CTRL_ON, metaState, down);
|
2022-06-05 19:30:53 +02:00
|
|
|
case ALT:
|
2022-06-05 01:38:42 +02:00
|
|
|
return sendMetaKey(KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_ON, metaState, down);
|
2022-06-05 19:30:53 +02:00
|
|
|
case SHIFT:
|
2022-06-05 01:38:42 +02:00
|
|
|
return sendMetaKey(KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON, metaState, down);
|
2022-06-05 19:30:53 +02:00
|
|
|
case META:
|
2022-06-05 01:38:42 +02:00
|
|
|
return sendMetaKey(KeyEvent.KEYCODE_META_LEFT, KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_ON, metaState, down);
|
|
|
|
default: return metaState;
|
|
|
|
}
|
2021-12-28 17:47:18 +01:00
|
|
|
}
|
|
|
|
|
2022-02-22 19:32:16 +01:00
|
|
|
/*
|
|
|
|
* Don't set KeyEvent.FLAG_SOFT_KEYBOARD.
|
|
|
|
*/
|
2022-11-13 16:18:08 +01:00
|
|
|
void handleKeyUpWithModifier(int keyCode, Pointers.Modifiers mods)
|
|
|
|
{
|
2022-06-05 01:38:42 +02:00
|
|
|
int metaState = 0;
|
|
|
|
for (int i = 0; i < mods.size(); i++)
|
|
|
|
metaState = sendMetaKeyForModifier(mods.get(i), metaState, true);
|
2022-11-13 16:18:08 +01:00
|
|
|
send_keyevent(KeyEvent.ACTION_DOWN, keyCode, metaState);
|
|
|
|
send_keyevent(KeyEvent.ACTION_UP, keyCode, metaState);
|
2022-06-05 01:38:42 +02:00
|
|
|
for (int i = mods.size() - 1; i >= 0; i--)
|
|
|
|
metaState = sendMetaKeyForModifier(mods.get(i), metaState, false);
|
2022-11-13 16:18:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void send_keyevent(int eventAction, int eventCode, int meta)
|
|
|
|
{
|
|
|
|
InputConnection conn = _recv.getCurrentInputConnection();
|
|
|
|
if (conn == null)
|
|
|
|
return;
|
|
|
|
conn.sendKeyEvent(new KeyEvent(1, 1, eventAction, eventCode, 0, meta));
|
|
|
|
if (eventAction == KeyEvent.ACTION_UP)
|
|
|
|
_autocap.event_sent(eventCode, meta);
|
|
|
|
}
|
|
|
|
|
|
|
|
void send_text(CharSequence text)
|
|
|
|
{
|
|
|
|
InputConnection conn = _recv.getCurrentInputConnection();
|
|
|
|
if (conn == null)
|
|
|
|
return;
|
|
|
|
conn.commitText(text, 1);
|
|
|
|
_autocap.typed(text);
|
|
|
|
}
|
2022-02-22 19:32:16 +01:00
|
|
|
|
2022-11-13 16:45:57 +01:00
|
|
|
/** See {!InputConnection.performContextMenuAction}. */
|
|
|
|
void send_context_menu_action(int id)
|
|
|
|
{
|
|
|
|
InputConnection conn = _recv.getCurrentInputConnection();
|
|
|
|
if (conn == null)
|
|
|
|
return;
|
|
|
|
conn.performContextMenuAction(id);
|
|
|
|
}
|
|
|
|
|
2021-12-28 17:47:18 +01:00
|
|
|
public static interface IReceiver
|
|
|
|
{
|
|
|
|
public void switchToNextInputMethod();
|
|
|
|
public void setPane_emoji();
|
|
|
|
public void setPane_normal();
|
|
|
|
public void showKeyboardConfig();
|
|
|
|
|
2022-12-29 12:43:02 +01:00
|
|
|
public void switch_text();
|
2022-11-13 16:18:08 +01:00
|
|
|
public void switch_second();
|
|
|
|
public void switch_layout(int layout_id);
|
|
|
|
|
|
|
|
public void set_shift_state(boolean state, boolean lock);
|
2021-12-28 17:47:18 +01:00
|
|
|
|
2022-11-13 16:18:08 +01:00
|
|
|
public InputConnection getCurrentInputConnection();
|
|
|
|
}
|
2021-12-28 17:47:18 +01:00
|
|
|
|
2022-11-13 16:18:08 +01:00
|
|
|
class Autocapitalisation_callback implements Autocapitalisation.Callback
|
|
|
|
{
|
|
|
|
@Override
|
|
|
|
public void update_shift_state(boolean should_enable, boolean should_disable)
|
|
|
|
{
|
|
|
|
if (should_enable)
|
|
|
|
_recv.set_shift_state(true, false);
|
|
|
|
else if (should_disable)
|
|
|
|
_recv.set_shift_state(false, false);
|
|
|
|
}
|
2021-12-28 17:47:18 +01:00
|
|
|
}
|
|
|
|
}
|