diff options
Diffstat (limited to 'java/src/com/android/inputmethod/event')
5 files changed, 50 insertions, 18 deletions
diff --git a/java/src/com/android/inputmethod/event/Combiner.java b/java/src/com/android/inputmethod/event/Combiner.java index 8b808c6b3..fee93f0c6 100644 --- a/java/src/com/android/inputmethod/event/Combiner.java +++ b/java/src/com/android/inputmethod/event/Combiner.java @@ -18,6 +18,8 @@ package com.android.inputmethod.event; import java.util.ArrayList; +import javax.annotation.Nonnull; + /** * A generic interface for combiners. Combiners are objects that transform chains of input events * into committable strings and manage feedback to show to the user on the combining state. @@ -33,6 +35,7 @@ public interface Combiner { * @param event the event to combine with the existing state. * @return the resulting event. */ + @Nonnull Event processEvent(ArrayList<Event> previousEvents, Event event); /** diff --git a/java/src/com/android/inputmethod/event/CombinerChain.java b/java/src/com/android/inputmethod/event/CombinerChain.java index 61bc11b39..f69bf4fd0 100644 --- a/java/src/com/android/inputmethod/event/CombinerChain.java +++ b/java/src/com/android/inputmethod/event/CombinerChain.java @@ -24,6 +24,8 @@ import com.android.inputmethod.latin.Constants; import java.util.ArrayList; import java.util.HashMap; +import javax.annotation.Nonnull; + /** * This class implements the logic chain between receiving events and generating code points. * @@ -81,22 +83,29 @@ public class CombinerChain { } /** - * Pass a new event through the whole chain. + * Process an event through the combining chain, and return a processed event to apply. * @param previousEvents the list of previous events in this composition * @param newEvent the new event to process + * @return the processed event. It may be the same event, or a consumed event, or a completely + * new event. However it may never be null. */ - public void processEvent(final ArrayList<Event> previousEvents, final Event newEvent) { + @Nonnull + public Event processEvent(final ArrayList<Event> previousEvents, final Event newEvent) { final ArrayList<Event> modifiablePreviousEvents = new ArrayList<>(previousEvents); Event event = newEvent; for (final Combiner combiner : mCombiners) { // A combiner can never return more than one event; it can return several // code points, but they should be encapsulated within one event. event = combiner.processEvent(modifiablePreviousEvents, event); - if (null == event) { - // Combiners return null if they eat the event. - break; - } } + return event; + } + + /** + * Apply a processed event. + * @param event the event to be applied + */ + public void applyProcessedEvent(final Event event) { if (null != event) { // TODO: figure out the generic way of doing this if (Constants.CODE_DELETE == event.mKeyCode) { diff --git a/java/src/com/android/inputmethod/event/DeadKeyCombiner.java b/java/src/com/android/inputmethod/event/DeadKeyCombiner.java index bef4d8594..d816247d8 100644 --- a/java/src/com/android/inputmethod/event/DeadKeyCombiner.java +++ b/java/src/com/android/inputmethod/event/DeadKeyCombiner.java @@ -23,6 +23,8 @@ import com.android.inputmethod.latin.Constants; import java.util.ArrayList; +import javax.annotation.Nonnull; + /** * A combiner that handles dead keys. */ @@ -31,13 +33,13 @@ public class DeadKeyCombiner implements Combiner { final StringBuilder mDeadSequence = new StringBuilder(); @Override + @Nonnull public Event processEvent(final ArrayList<Event> previousEvents, final Event event) { - if (null == event) return null; // Just in case some combiner is broken if (TextUtils.isEmpty(mDeadSequence)) { if (event.isDead()) { mDeadSequence.appendCodePoint(event.mCodePoint); } - return event; + return Event.createConsumedEvent(event); } else { // TODO: Allow combining for several dead chars rather than only the first one. // The framework doesn't know how to do this now. diff --git a/java/src/com/android/inputmethod/event/Event.java b/java/src/com/android/inputmethod/event/Event.java index d257441e0..98c827423 100644 --- a/java/src/com/android/inputmethod/event/Event.java +++ b/java/src/com/android/inputmethod/event/Event.java @@ -67,6 +67,8 @@ public class Event { final private static int FLAG_DEAD = 0x1; // This event is coming from a key repeat, software or hardware. final private static int FLAG_REPEAT = 0x2; + // This event has already been consumed. + final private static int FLAG_CONSUMED = 0x4; final private int mEventType; // The type of event - one of the constants above // The code point associated with the event, if relevant. This is a unicode code point, and @@ -219,6 +221,17 @@ public class Event { null /* next */); } + /** + * Creates an event identical to the passed event, but that has already been consumed. + * @param source the event to copy the properties of. + * @return an identical event marked as consumed. + */ + public static Event createConsumedEvent(final Event source) { + return new Event(source.mEventType, source.mText, source.mCodePoint, source.mKeyCode, + source.mX, source.mY, source.mSuggestedWordInfo, source.mFlags | FLAG_CONSUMED, + source.mNextEvent); + } + public static Event createNotHandledEvent() { return new Event(EVENT_TYPE_NOT_HANDLED, null /* text */, NOT_A_CODE_POINT, NOT_A_KEY_CODE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, @@ -241,6 +254,8 @@ public class Event { return 0 != (FLAG_REPEAT & mFlags); } + public boolean isConsumed() { return 0 != (FLAG_CONSUMED & mFlags); } + // Returns whether this is a fake key press from the suggestion strip. This happens with // punctuation signs selected from the suggestion strip. public boolean isSuggestionStripPress() { diff --git a/java/src/com/android/inputmethod/event/MyanmarReordering.java b/java/src/com/android/inputmethod/event/MyanmarReordering.java index 32919932d..dcd06c899 100644 --- a/java/src/com/android/inputmethod/event/MyanmarReordering.java +++ b/java/src/com/android/inputmethod/event/MyanmarReordering.java @@ -21,6 +21,8 @@ import com.android.inputmethod.latin.Constants; import java.util.ArrayList; import java.util.Arrays; +import javax.annotation.Nonnull; + /** * A combiner that reorders input for Myanmar. */ @@ -111,7 +113,7 @@ public class MyanmarReordering implements Combiner { * Clears the currently combining stream of events and returns the resulting software text * event corresponding to the stream. Optionally adds a new event to the cleared stream. * @param newEvent the new event to add to the stream. null if none. - * @return the resulting software text event. Null if none. + * @return the resulting software text event. Never null. */ private Event clearAndGetResultingEvent(final Event newEvent) { final CharSequence combinedText; @@ -124,18 +126,19 @@ public class MyanmarReordering implements Combiner { if (null != newEvent) { mCurrentEvents.add(newEvent); } - return null == combinedText ? null + return null == combinedText ? Event.createConsumedEvent(newEvent) : Event.createSoftwareTextEvent(combinedText, Event.NOT_A_KEY_CODE); } @Override + @Nonnull public Event processEvent(ArrayList<Event> previousEvents, Event newEvent) { final int codePoint = newEvent.mCodePoint; if (VOWEL_E == codePoint) { final Event lastEvent = getLastEvent(); if (null == lastEvent) { mCurrentEvents.add(newEvent); - return null; + return Event.createConsumedEvent(newEvent); } else if (isConsonantOrMedial(lastEvent.mCodePoint)) { final Event resultingEvent = clearAndGetResultingEvent(null); mCurrentEvents.add(Event.createSoftwareKeypressEvent(ZERO_WIDTH_NON_JOINER, @@ -151,7 +154,7 @@ public class MyanmarReordering implements Combiner { final Event lastEvent = getLastEvent(); if (null == lastEvent) { mCurrentEvents.add(newEvent); - return null; + return Event.createConsumedEvent(newEvent); } else if (VOWEL_E == lastEvent.mCodePoint) { final int eventSize = mCurrentEvents.size(); if (eventSize >= 2 @@ -162,7 +165,7 @@ public class MyanmarReordering implements Combiner { mCurrentEvents.remove(eventSize - 2); mCurrentEvents.add(newEvent); mCurrentEvents.add(lastEvent); - return null; + return Event.createConsumedEvent(newEvent); } // If there is already a consonant, then we are starting a new syllable. for (int i = eventSize - 2; i >= 0; --i) { @@ -174,7 +177,7 @@ public class MyanmarReordering implements Combiner { mCurrentEvents.remove(eventSize - 1); mCurrentEvents.add(newEvent); mCurrentEvents.add(lastEvent); - return null; + return Event.createConsumedEvent(newEvent); } else { // lastCodePoint is a consonant/medial. But if it's something else it's fine return clearAndGetResultingEvent(newEvent); } @@ -182,7 +185,7 @@ public class MyanmarReordering implements Combiner { final Event lastEvent = getLastEvent(); if (null == lastEvent) { mCurrentEvents.add(newEvent); - return null; + return Event.createConsumedEvent(newEvent); } else if (VOWEL_E == lastEvent.mCodePoint) { final int eventSize = mCurrentEvents.size(); // If there is already a consonant, then we are in the middle of a syllable, and we @@ -198,7 +201,7 @@ public class MyanmarReordering implements Combiner { mCurrentEvents.remove(eventSize - 1); mCurrentEvents.add(newEvent); mCurrentEvents.add(lastEvent); - return null; + return Event.createConsumedEvent(newEvent); } // Otherwise, we just commit everything. return clearAndGetResultingEvent(null); @@ -228,10 +231,10 @@ public class MyanmarReordering implements Combiner { mCurrentEvents.remove(eventSize - 1); } } - return null; + return Event.createConsumedEvent(newEvent); } else if (eventSize > 0) { mCurrentEvents.remove(eventSize - 1); - return null; + return Event.createConsumedEvent(newEvent); } } } |