Merge "[CB11] Get the result of the combination"

main
Jean Chalard 2014-03-24 05:33:34 +00:00 committed by Android (Google) Code Review
commit 7f0e5fa66c
6 changed files with 68 additions and 6 deletions

View File

@ -34,4 +34,10 @@ public interface Combiner {
* @return the resulting event. * @return the resulting event.
*/ */
Event processEvent(ArrayList<Event> previousEvents, Event event); Event processEvent(ArrayList<Event> previousEvents, Event event);
/**
* Get the feedback that should be shown to the user for the current state of this combiner.
* @return A CharSequence representing the feedback to show users. It may include styles.
*/
CharSequence getCombiningStateFeedback();
} }

View File

@ -16,6 +16,8 @@
package com.android.inputmethod.event; package com.android.inputmethod.event;
import android.text.SpannableStringBuilder;
import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.CollectionUtils;
import java.util.ArrayList; import java.util.ArrayList;
@ -33,8 +35,10 @@ import java.util.ArrayList;
* a colored background. * a colored background.
*/ */
public class CombinerChain { public class CombinerChain {
// TODO: Create an object type to represent input material + visual feedback + decoding state // The already combined text, as described above
private StringBuilder mCombinedText;
// The feedback on the composing state, as described above
private SpannableStringBuilder mStateFeedback;
private final ArrayList<Combiner> mCombiners; private final ArrayList<Combiner> mCombiners;
/** /**
@ -50,9 +54,15 @@ public class CombinerChain {
mCombiners = CollectionUtils.newArrayList(); mCombiners = CollectionUtils.newArrayList();
// The dead key combiner is always active, and always first // The dead key combiner is always active, and always first
mCombiners.add(new DeadKeyCombiner()); mCombiners.add(new DeadKeyCombiner());
mCombinedText = new StringBuilder();
mStateFeedback = new SpannableStringBuilder();
} }
// Pass a new event through the whole chain. /**
* Pass a new event through the whole chain.
* @param previousEvents the list of previous events in this composition
* @param newEvent the new event to process
*/
public void processEvent(final ArrayList<Event> previousEvents, final Event newEvent) { public void processEvent(final ArrayList<Event> previousEvents, final Event newEvent) {
final ArrayList<Event> modifiablePreviousEvents = new ArrayList<Event>(previousEvents); final ArrayList<Event> modifiablePreviousEvents = new ArrayList<Event>(previousEvents);
Event event = newEvent; Event event = newEvent;
@ -62,8 +72,24 @@ public class CombinerChain {
event = combiner.processEvent(modifiablePreviousEvents, event); event = combiner.processEvent(modifiablePreviousEvents, event);
if (null == event) { if (null == event) {
// Combiners return null if they eat the event. // Combiners return null if they eat the event.
return; break;
} }
} }
if (null != event) {
mCombinedText.append(event.getTextToCommit());
}
mStateFeedback.clear();
for (int i = mCombiners.size() - 1; i >= 0; --i) {
mStateFeedback.append(mCombiners.get(i).getCombiningStateFeedback());
}
}
/**
* Get the char sequence that should be displayed as the composing word. It may include
* styling spans.
*/
public CharSequence getComposingWordWithCombiningFeedback() {
final SpannableStringBuilder s = new SpannableStringBuilder(mCombinedText);
return s.append(mStateFeedback);
} }
} }

View File

@ -61,4 +61,9 @@ public class DeadKeyCombiner implements Combiner {
} }
} }
} }
@Override
public CharSequence getCombiningStateFeedback() {
return mDeadSequence;
}
} }

View File

@ -18,6 +18,7 @@ package com.android.inputmethod.event;
import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.utils.StringUtils;
/** /**
* Class representing a generic input event as handled by Latin IME. * Class representing a generic input event as handled by Latin IME.
@ -223,4 +224,19 @@ public class Event {
public boolean isHandled() { public boolean isHandled() {
return EVENT_NOT_HANDLED != mType; return EVENT_NOT_HANDLED != mType;
} }
public CharSequence getTextToCommit() {
switch (mType) {
case EVENT_MODE_KEY:
case EVENT_NOT_HANDLED:
return "";
case EVENT_INPUT_KEYPRESS:
case EVENT_TOGGLE:
return StringUtils.newSingleCodePointString(mCodePoint);
case EVENT_GESTURE:
case EVENT_SOFTWARE_GENERATED_STRING:
return mText;
}
throw new RuntimeException("Unknown event type: " + mType);
}
} }

View File

@ -193,7 +193,10 @@ public final class WordComposer {
final int keyY = event.mY; final int keyY = event.mY;
final int newIndex = size(); final int newIndex = size();
mCombinerChain.processEvent(mEvents, event); mCombinerChain.processEvent(mEvents, event);
mTypedWord.appendCodePoint(primaryCode); // TODO: remove mTypedWord and compute it dynamically when necessary. We also need to
// make the views of the composing word a SpannableString.
mTypedWord.replace(0, mTypedWord.length(),
mCombinerChain.getComposingWordWithCombiningFeedback().toString());
mEvents.add(event); mEvents.add(event);
refreshSize(); refreshSize();
mCursorPositionWithinWord = mCodePointSize; mCursorPositionWithinWord = mCodePointSize;

View File

@ -21,6 +21,12 @@ import com.android.inputmethod.latin.utils.CollectionUtils;
import java.util.ArrayList; import java.util.ArrayList;
public class CombinerChain { public class CombinerChain {
private StringBuilder mComposingWord = new StringBuilder();
public CombinerChain(final Combiner... combinerList) {} public CombinerChain(final Combiner... combinerList) {}
public void processEvent(final ArrayList<Event> previousEvents, final Event newEvent) {} public void processEvent(final ArrayList<Event> previousEvents, final Event newEvent) {
mComposingWord.append(newEvent.getTextToCommit());
}
public CharSequence getComposingWordWithCombiningFeedback() {
return mComposingWord;
}
} }