diff options
Diffstat (limited to 'srcs')
| -rw-r--r-- | srcs/juloo.keyboard2/ComposeKey.java | 12 | ||||
| -rw-r--r-- | srcs/juloo.keyboard2/Config.java | 2 | ||||
| -rw-r--r-- | srcs/juloo.keyboard2/CurrentlyTypedWord.java | 8 | ||||
| -rw-r--r-- | srcs/juloo.keyboard2/KeyEventHandler.java | 57 | ||||
| -rw-r--r-- | srcs/juloo.keyboard2/KeyModifier.java | 161 | ||||
| -rw-r--r-- | srcs/juloo.keyboard2/KeyValue.java | 13 | ||||
| -rw-r--r-- | srcs/juloo.keyboard2/suggestions/Suggestions.java | 14 |
7 files changed, 187 insertions, 80 deletions
diff --git a/srcs/juloo.keyboard2/ComposeKey.java b/srcs/juloo.keyboard2/ComposeKey.java index 9571c03..5be9597 100644 --- a/srcs/juloo.keyboard2/ComposeKey.java +++ b/srcs/juloo.keyboard2/ComposeKey.java @@ -10,10 +10,14 @@ public final class ComposeKey { switch (kv.getKind()) { - case Char: - return apply(state, kv.getChar()); - case String: - return apply(state, kv.getString()); + case Char: return apply(state, kv.getChar()); + case String: return apply(state, kv.getString()); + case Editing: + switch (kv.getEditing()) + { + case SPACE_BAR: return apply(state, ' '); + } + break; } return null; } diff --git a/srcs/juloo.keyboard2/Config.java b/srcs/juloo.keyboard2/Config.java index 2831254..98bb72b 100644 --- a/srcs/juloo.keyboard2/Config.java +++ b/srcs/juloo.keyboard2/Config.java @@ -74,6 +74,7 @@ public final class Config public int circle_sensitivity; public boolean clipboard_history_enabled; public int clipboard_history_duration; + public boolean space_bar_auto_complete; // Dynamically set /** Configuration options implied by the connected editor. */ @@ -191,6 +192,7 @@ public final class Config circle_sensitivity = Integer.valueOf(_prefs.getString("circle_sensitivity", "2")); clipboard_history_enabled = _prefs.getBoolean("clipboard_history_enabled", false); clipboard_history_duration = Integer.parseInt(_prefs.getString("clipboard_history_duration", "5")); + space_bar_auto_complete = _prefs.getBoolean("space_bar_auto_complete", false); float screen_width_dp = dm.widthPixels / dm.density; wide_screen = screen_width_dp >= WIDE_DEVICE_THRESHOLD; diff --git a/srcs/juloo.keyboard2/CurrentlyTypedWord.java b/srcs/juloo.keyboard2/CurrentlyTypedWord.java index 8685fb1..40825bb 100644 --- a/srcs/juloo.keyboard2/CurrentlyTypedWord.java +++ b/srcs/juloo.keyboard2/CurrentlyTypedWord.java @@ -6,7 +6,8 @@ import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import java.util.List; -/** Keep track of the word being typed. */ +/** Keep track of the word being typed. This also tracks whether the selection + is empty. */ public final class CurrentlyTypedWord { InputConnection _ic = null; @@ -40,6 +41,11 @@ public final class CurrentlyTypedWord return _w.toString(); } + public boolean is_selection_not_empty() + { + return _has_selection; + } + public void started(Config conf, InputConnection ic) { _ic = ic; diff --git a/srcs/juloo.keyboard2/KeyEventHandler.java b/srcs/juloo.keyboard2/KeyEventHandler.java index 2bda20c..d078a63 100644 --- a/srcs/juloo.keyboard2/KeyEventHandler.java +++ b/srcs/juloo.keyboard2/KeyEventHandler.java @@ -30,6 +30,8 @@ public final class KeyEventHandler /** Whether to force sending arrow keys to move the cursor when [setSelection] could be used instead. */ boolean _move_cursor_force_fallback = false; + /** Whether the space bar automatically enters the best suggestion. */ + boolean _space_bar_auto_complete = false; public KeyEventHandler(IReceiver recv, Config config) { @@ -50,6 +52,8 @@ public final class KeyEventHandler _typedword.started(conf, ic); _move_cursor_force_fallback = conf.editor_config.should_move_cursor_force_fallback; + _space_bar_auto_complete = conf.space_bar_auto_complete; + clear_space_bar_state(); } /** Selection has been updated. */ @@ -123,7 +127,10 @@ public final class KeyEventHandler @Override public void suggestion_entered(String text) { - replace_text_before_cursor(_typedword.get().length(), text + " "); + String old = _typedword.get(); + replace_text_before_cursor(old.length(), text + " "); + last_replaced_word = old; + last_replacement_word_len = text.length() + 1; } @Override @@ -227,6 +234,7 @@ public final class KeyEventHandler { _autocap.event_sent(eventCode, metaState); _typedword.event_sent(eventCode, metaState); + clear_space_bar_state(); } } @@ -238,6 +246,7 @@ public final class KeyEventHandler _autocap.typed(text); _typedword.typed(text); conn.commitText(text, 1); + clear_space_bar_state(); } void replace_text_before_cursor(int remove_length, String new_text) @@ -265,9 +274,9 @@ public final class KeyEventHandler { switch (ev) { - case COPY: if(is_selection_not_empty()) send_context_menu_action(android.R.id.copy); break; + case COPY: if(_typedword.is_selection_not_empty()) send_context_menu_action(android.R.id.copy); break; case PASTE: send_context_menu_action(android.R.id.paste); break; - case CUT: if(is_selection_not_empty()) send_context_menu_action(android.R.id.cut); break; + case CUT: if(_typedword.is_selection_not_empty()) send_context_menu_action(android.R.id.cut); break; case SELECT_ALL: send_context_menu_action(android.R.id.selectAll); break; case SHARE: send_context_menu_action(android.R.id.shareText); break; case PASTE_PLAIN: send_context_menu_action(android.R.id.pasteAsPlainText); break; @@ -279,6 +288,8 @@ public final class KeyEventHandler case DELETE_WORD: send_key_down_up(KeyEvent.KEYCODE_DEL, KeyEvent.META_CTRL_ON | KeyEvent.META_CTRL_LEFT_ON); break; case FORWARD_DELETE_WORD: send_key_down_up(KeyEvent.KEYCODE_FORWARD_DEL, KeyEvent.META_CTRL_ON | KeyEvent.META_CTRL_LEFT_ON); break; case SELECTION_CANCEL: cancel_selection(); break; + case SPACE_BAR: handle_space_bar(); break; + case BACKSPACE: handle_backspace(); break; } } @@ -497,11 +508,43 @@ public final class KeyEventHandler _recv.selection_state_changed(false); } - boolean is_selection_not_empty() + /** The word that was replaced by a suggestion when the last action was to + enter a suggestion (with the space bar or the candidates view) or [null] + otherwise. */ + String last_replaced_word = null; + /** Length of the text before the cursor that should be replaced by + backspace. */ + int last_replacement_word_len = 0; + + void handle_space_bar() { - InputConnection conn = _recv.getCurrentInputConnection(); - if (conn == null) return false; - return (conn.getSelectedText(0) != null); + if (_space_bar_auto_complete && _suggestions.best_suggestion != null + && !_typedword.is_selection_not_empty()) + { + suggestion_entered(_suggestions.best_suggestion); + } + else + { + send_text(" "); + } + } + + void handle_backspace() + { + if (last_replaced_word != null) + { + replace_text_before_cursor(last_replacement_word_len, last_replaced_word); + last_replaced_word = null; + } + else + { + send_key_down_up(KeyEvent.KEYCODE_DEL); + } + } + + void clear_space_bar_state() + { + last_replaced_word = null; } public static interface IReceiver extends Suggestions.Callback diff --git a/srcs/juloo.keyboard2/KeyModifier.java b/srcs/juloo.keyboard2/KeyModifier.java index c40c342..3ef16bc 100644 --- a/srcs/juloo.keyboard2/KeyModifier.java +++ b/srcs/juloo.keyboard2/KeyModifier.java @@ -178,15 +178,26 @@ public final class KeyModifier private static KeyValue apply_dead_char(KeyValue k, char dead_char) { + KeyValue r = null; switch (k.getKind()) { - case Char: - char c = k.getChar(); - char modified = (char)KeyCharacterMap.getDeadChar(dead_char, c); - if (modified != 0 && modified != c) - return KeyValue.makeStringKey(String.valueOf(modified)); + case Char: r = apply_dead_char(k.getChar(), dead_char); break; + case Editing: + switch (k.getEditing()) + { + case SPACE_BAR: r = apply_dead_char(' ', dead_char); break; + } + break; } - return k; + return (r == null) ? k : r; + } + + private static KeyValue apply_dead_char(char c, char dead_char) + { + char modified = (char)KeyCharacterMap.getDeadChar(dead_char, c); + if (modified != 0 && modified != c) + return KeyValue.makeStringKey(String.valueOf(modified)); + return null; } private static KeyValue apply_combining_char(KeyValue k, String combining) @@ -294,6 +305,7 @@ public final class KeyModifier { case UNDO: return "redo"; case PASTE: return "pasteAsPlainText"; + case SPACE_BAR: return "nbsp"; default: return null; } } @@ -313,65 +325,76 @@ public final class KeyModifier private static KeyValue turn_into_keyevent(KeyValue k) { - if (k.getKind() != KeyValue.Kind.Char) - return k; int e; - switch (k.getChar()) + switch (k.getKind()) { - case 'a': e = KeyEvent.KEYCODE_A; break; - case 'b': e = KeyEvent.KEYCODE_B; break; - case 'c': e = KeyEvent.KEYCODE_C; break; - case 'd': e = KeyEvent.KEYCODE_D; break; - case 'e': e = KeyEvent.KEYCODE_E; break; - case 'f': e = KeyEvent.KEYCODE_F; break; - case 'g': e = KeyEvent.KEYCODE_G; break; - case 'h': e = KeyEvent.KEYCODE_H; break; - case 'i': e = KeyEvent.KEYCODE_I; break; - case 'j': e = KeyEvent.KEYCODE_J; break; - case 'k': e = KeyEvent.KEYCODE_K; break; - case 'l': e = KeyEvent.KEYCODE_L; break; - case 'm': e = KeyEvent.KEYCODE_M; break; - case 'n': e = KeyEvent.KEYCODE_N; break; - case 'o': e = KeyEvent.KEYCODE_O; break; - case 'p': e = KeyEvent.KEYCODE_P; break; - case 'q': e = KeyEvent.KEYCODE_Q; break; - case 'r': e = KeyEvent.KEYCODE_R; break; - case 's': e = KeyEvent.KEYCODE_S; break; - case 't': e = KeyEvent.KEYCODE_T; break; - case 'u': e = KeyEvent.KEYCODE_U; break; - case 'v': e = KeyEvent.KEYCODE_V; break; - case 'w': e = KeyEvent.KEYCODE_W; break; - case 'x': e = KeyEvent.KEYCODE_X; break; - case 'y': e = KeyEvent.KEYCODE_Y; break; - case 'z': e = KeyEvent.KEYCODE_Z; break; - case '0': e = KeyEvent.KEYCODE_0; break; - case '1': e = KeyEvent.KEYCODE_1; break; - case '2': e = KeyEvent.KEYCODE_2; break; - case '3': e = KeyEvent.KEYCODE_3; break; - case '4': e = KeyEvent.KEYCODE_4; break; - case '5': e = KeyEvent.KEYCODE_5; break; - case '6': e = KeyEvent.KEYCODE_6; break; - case '7': e = KeyEvent.KEYCODE_7; break; - case '8': e = KeyEvent.KEYCODE_8; break; - case '9': e = KeyEvent.KEYCODE_9; break; - case '`': e = KeyEvent.KEYCODE_GRAVE; break; - case '-': e = KeyEvent.KEYCODE_MINUS; break; - case '=': e = KeyEvent.KEYCODE_EQUALS; break; - case '[': e = KeyEvent.KEYCODE_LEFT_BRACKET; break; - case ']': e = KeyEvent.KEYCODE_RIGHT_BRACKET; break; - case '\\': e = KeyEvent.KEYCODE_BACKSLASH; break; - case ';': e = KeyEvent.KEYCODE_SEMICOLON; break; - case '\'': e = KeyEvent.KEYCODE_APOSTROPHE; break; - case '/': e = KeyEvent.KEYCODE_SLASH; break; - case '@': e = KeyEvent.KEYCODE_AT; break; - case '+': e = KeyEvent.KEYCODE_PLUS; break; - case ',': e = KeyEvent.KEYCODE_COMMA; break; - case '.': e = KeyEvent.KEYCODE_PERIOD; break; - case '*': e = KeyEvent.KEYCODE_STAR; break; - case '#': e = KeyEvent.KEYCODE_POUND; break; - case '(': e = KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN; break; - case ')': e = KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN; break; - case ' ': e = KeyEvent.KEYCODE_SPACE; break; + case Char: + switch (k.getChar()) + { + case 'a': e = KeyEvent.KEYCODE_A; break; + case 'b': e = KeyEvent.KEYCODE_B; break; + case 'c': e = KeyEvent.KEYCODE_C; break; + case 'd': e = KeyEvent.KEYCODE_D; break; + case 'e': e = KeyEvent.KEYCODE_E; break; + case 'f': e = KeyEvent.KEYCODE_F; break; + case 'g': e = KeyEvent.KEYCODE_G; break; + case 'h': e = KeyEvent.KEYCODE_H; break; + case 'i': e = KeyEvent.KEYCODE_I; break; + case 'j': e = KeyEvent.KEYCODE_J; break; + case 'k': e = KeyEvent.KEYCODE_K; break; + case 'l': e = KeyEvent.KEYCODE_L; break; + case 'm': e = KeyEvent.KEYCODE_M; break; + case 'n': e = KeyEvent.KEYCODE_N; break; + case 'o': e = KeyEvent.KEYCODE_O; break; + case 'p': e = KeyEvent.KEYCODE_P; break; + case 'q': e = KeyEvent.KEYCODE_Q; break; + case 'r': e = KeyEvent.KEYCODE_R; break; + case 's': e = KeyEvent.KEYCODE_S; break; + case 't': e = KeyEvent.KEYCODE_T; break; + case 'u': e = KeyEvent.KEYCODE_U; break; + case 'v': e = KeyEvent.KEYCODE_V; break; + case 'w': e = KeyEvent.KEYCODE_W; break; + case 'x': e = KeyEvent.KEYCODE_X; break; + case 'y': e = KeyEvent.KEYCODE_Y; break; + case 'z': e = KeyEvent.KEYCODE_Z; break; + case '0': e = KeyEvent.KEYCODE_0; break; + case '1': e = KeyEvent.KEYCODE_1; break; + case '2': e = KeyEvent.KEYCODE_2; break; + case '3': e = KeyEvent.KEYCODE_3; break; + case '4': e = KeyEvent.KEYCODE_4; break; + case '5': e = KeyEvent.KEYCODE_5; break; + case '6': e = KeyEvent.KEYCODE_6; break; + case '7': e = KeyEvent.KEYCODE_7; break; + case '8': e = KeyEvent.KEYCODE_8; break; + case '9': e = KeyEvent.KEYCODE_9; break; + case '`': e = KeyEvent.KEYCODE_GRAVE; break; + case '-': e = KeyEvent.KEYCODE_MINUS; break; + case '=': e = KeyEvent.KEYCODE_EQUALS; break; + case '[': e = KeyEvent.KEYCODE_LEFT_BRACKET; break; + case ']': e = KeyEvent.KEYCODE_RIGHT_BRACKET; break; + case '\\': e = KeyEvent.KEYCODE_BACKSLASH; break; + case ';': e = KeyEvent.KEYCODE_SEMICOLON; break; + case '\'': e = KeyEvent.KEYCODE_APOSTROPHE; break; + case '/': e = KeyEvent.KEYCODE_SLASH; break; + case '@': e = KeyEvent.KEYCODE_AT; break; + case '+': e = KeyEvent.KEYCODE_PLUS; break; + case ',': e = KeyEvent.KEYCODE_COMMA; break; + case '.': e = KeyEvent.KEYCODE_PERIOD; break; + case '*': e = KeyEvent.KEYCODE_STAR; break; + case '#': e = KeyEvent.KEYCODE_POUND; break; + case '(': e = KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN; break; + case ')': e = KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN; break; + case ' ': e = KeyEvent.KEYCODE_SPACE; break; + default: return k; + } + break; + case Editing: + switch (k.getEditing()) + { + case SPACE_BAR: e = KeyEvent.KEYCODE_SPACE; break; + default: return k; + } + break; default: return k; } return k.withKeyevent(e); @@ -409,6 +432,12 @@ public final class KeyModifier case KeyEvent.KEYCODE_FORWARD_DEL: name = "forward_delete_word"; break; } break; + case Editing: + switch (k.getEditing()) + { + case BACKSPACE: name = "delete_word"; break; + } + break; } return (name == null) ? k : KeyValue.getKeyByName(name); } @@ -437,6 +466,12 @@ public final class KeyModifier case KeyEvent.KEYCODE_ESCAPE: name = "selection_cancel"; break; } break; + case Editing: + switch (k.getEditing()) + { + case SPACE_BAR: name = "selection_cancel"; break; + } + break; } return (name == null) ? k : KeyValue.getKeyByName(name); } diff --git a/srcs/juloo.keyboard2/KeyValue.java b/srcs/juloo.keyboard2/KeyValue.java index 1fb84f4..769bd29 100644 --- a/srcs/juloo.keyboard2/KeyValue.java +++ b/srcs/juloo.keyboard2/KeyValue.java @@ -81,6 +81,8 @@ public final class KeyValue implements Comparable<KeyValue> DELETE_WORD, FORWARD_DELETE_WORD, SELECTION_CANCEL, + SPACE_BAR, + BACKSPACE, } public static enum Placeholder @@ -401,7 +403,12 @@ public final class KeyValue implements Comparable<KeyValue> private static KeyValue editingKey(int symbol, Editing action) { - return editingKey(String.valueOf((char)symbol), action, FLAG_KEY_FONT); + return editingKey(symbol, action, 0); + } + + private static KeyValue editingKey(int symbol, Editing action, int flags) + { + return editingKey(String.valueOf((char)symbol), action, flags | FLAG_KEY_FONT); } /** A key that slides the property specified by [s] by the amount specified @@ -658,7 +665,6 @@ public final class KeyValue implements Comparable<KeyValue> case "page_down": return keyeventKey(0xE003, KeyEvent.KEYCODE_PAGE_DOWN, 0); case "home": return keyeventKey(0xE00B, KeyEvent.KEYCODE_MOVE_HOME, FLAG_SMALLER_FONT); case "end": return keyeventKey(0xE00C, KeyEvent.KEYCODE_MOVE_END, FLAG_SMALLER_FONT); - case "backspace": return keyeventKey(0xE011, KeyEvent.KEYCODE_DEL, 0); case "delete": return keyeventKey(0xE010, KeyEvent.KEYCODE_FORWARD_DEL, 0); case "insert": return keyeventKey("Ins", KeyEvent.KEYCODE_INSERT, FLAG_SMALLER_FONT); case "f1": return keyeventKey("F1", KeyEvent.KEYCODE_F1, 0); @@ -680,7 +686,7 @@ public final class KeyValue implements Comparable<KeyValue> /* Spaces */ case "\\t": return charKey("\\t", '\t', 0); // Send the tab character case "\\n": return charKey("\\n", '\n', 0); // Send the newline character - case "space": return charKey(0xE00D, ' ', FLAG_SMALLER_FONT | FLAG_GREYED); + case "space": return editingKey(0xE00D, Editing.SPACE_BAR, FLAG_SMALLER_FONT | FLAG_GREYED); case "nbsp": return charKey("\u237d", '\u00a0', FLAG_SMALLER_FONT); case "nnbsp": return charKey("\u2423", '\u202F', FLAG_SMALLER_FONT); @@ -729,6 +735,7 @@ public final class KeyValue implements Comparable<KeyValue> case "halfspace": return charKey(0xE018, '\u200C', 0); // zero-width non joiner /* Editing keys */ + case "backspace": return editingKey(0xE011, Editing.BACKSPACE, 0); case "copy": return editingKey(0xE030, Editing.COPY); case "paste": return editingKey(0xE032, Editing.PASTE); case "cut": return editingKey(0xE031, Editing.CUT); diff --git a/srcs/juloo.keyboard2/suggestions/Suggestions.java b/srcs/juloo.keyboard2/suggestions/Suggestions.java index 998d40d..89ed86e 100644 --- a/srcs/juloo.keyboard2/suggestions/Suggestions.java +++ b/srcs/juloo.keyboard2/suggestions/Suggestions.java @@ -13,6 +13,10 @@ public final class Suggestions Callback _callback; Config _config; + /** The suggestion displayed at the center of the candidates view and entered + by the space bar. */ + public String best_suggestion = null; + public Suggestions(Callback c, Config conf) { _callback = c; @@ -24,7 +28,7 @@ public final class Suggestions Cdict dict = _config.current_dictionary; if (word.length() < 2 || dict == null) { - _callback.set_suggestions(NO_SUGGESTIONS); + set_suggestions(NO_SUGGESTIONS); } else { @@ -42,10 +46,16 @@ public final class Suggestions if (dist.length > j && i < 3) suggestions[i++] = dict.word(dist[j]); } - _callback.set_suggestions(Arrays.asList(suggestions)); + set_suggestions(Arrays.asList(suggestions)); } } + void set_suggestions(List<String> ws) + { + _callback.set_suggestions(ws); + best_suggestion = (ws.size() > 0) ? ws.get(0) : null; + } + static final List<String> NO_SUGGESTIONS = Arrays.asList(); public static interface Callback |
