am 3a1be7e4: Merge "Unbundle Key preview text and PointerTracker"

* commit '3a1be7e4cf1f1f30d02d50d142724731d02af90c':
  Unbundle Key preview text and PointerTracker
main
Tadashi G. Takaoka 2013-11-19 21:49:45 -08:00 committed by Android Git Automerger
commit 17737ccf51
2 changed files with 71 additions and 72 deletions

View File

@ -34,7 +34,6 @@ import android.preference.PreferenceManager;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
import android.util.SparseArray;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MotionEvent; import android.view.MotionEvent;
@ -71,6 +70,9 @@ import com.android.inputmethod.latin.utils.UsabilityStudyLogUtils;
import com.android.inputmethod.latin.utils.ViewLayoutUtils; import com.android.inputmethod.latin.utils.ViewLayoutUtils;
import com.android.inputmethod.research.ResearchLogger; import com.android.inputmethod.research.ResearchLogger;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.WeakHashMap; import java.util.WeakHashMap;
/** /**
@ -158,7 +160,10 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
private final int mKeyPreviewLayoutId; private final int mKeyPreviewLayoutId;
private final int mKeyPreviewOffset; private final int mKeyPreviewOffset;
private final int mKeyPreviewHeight; private final int mKeyPreviewHeight;
private final SparseArray<TextView> mKeyPreviewTexts = CollectionUtils.newSparseArray(); // Free {@link TextView} pool that can be used for key preview.
private final ArrayDeque<TextView> mFreeKeyPreviewTextViews = CollectionUtils.newArrayDeque();
// Map from {@link Key} to {@link TextView} that is currently being displayed as key preview.
private final HashMap<Key,TextView> mShowingKeyPreviewTextViews = CollectionUtils.newHashMap();
private final KeyPreviewDrawParams mKeyPreviewDrawParams = new KeyPreviewDrawParams(); private final KeyPreviewDrawParams mKeyPreviewDrawParams = new KeyPreviewDrawParams();
private boolean mShowKeyPreviewPopup = true; private boolean mShowKeyPreviewPopup = true;
private int mKeyPreviewLingerTimeout; private int mKeyPreviewLingerTimeout;
@ -381,13 +386,16 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
public void handleMessage(final Message msg) { public void handleMessage(final Message msg) {
final MainKeyboardView mainKeyboardView = getOuterInstance(); final MainKeyboardView mainKeyboardView = getOuterInstance();
if (mainKeyboardView == null) return; if (mainKeyboardView == null) return;
final PointerTracker tracker = (PointerTracker) msg.obj;
switch (msg.what) { switch (msg.what) {
case MSG_DISMISS_KEY_PREVIEW: case MSG_DISMISS_KEY_PREVIEW:
final TextView previewText = mainKeyboardView.mKeyPreviewTexts.get( final Key key = (Key)msg.obj;
tracker.mPointerId); if (key != null) {
if (previewText != null) { final TextView previewTextView =
previewText.setVisibility(INVISIBLE); mainKeyboardView.mShowingKeyPreviewTextViews.remove(key);
if (previewTextView != null) {
previewTextView.setVisibility(INVISIBLE);
mainKeyboardView.mFreeKeyPreviewTextViews.add(previewTextView);
}
} }
break; break;
case MSG_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT: case MSG_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT:
@ -396,12 +404,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
} }
} }
public void dismissKeyPreview(final long delay, final PointerTracker tracker) { public void dismissKeyPreview(final long delay, final Key key) {
sendMessageDelayed(obtainMessage(MSG_DISMISS_KEY_PREVIEW, tracker), delay); sendMessageDelayed(obtainMessage(MSG_DISMISS_KEY_PREVIEW, key), delay);
}
public void cancelDismissKeyPreview(final PointerTracker tracker) {
removeMessages(MSG_DISMISS_KEY_PREVIEW, tracker);
} }
private void cancelAllDismissKeyPreviews() { private void cancelAllDismissKeyPreviews() {
@ -681,33 +685,34 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
return mShowKeyPreviewPopup; return mShowKeyPreviewPopup;
} }
private void addKeyPreview(final TextView keyPreview) { private TextView getKeyPreviewTextView(final Key key) {
locatePreviewPlacerView(); TextView previewTextView = mShowingKeyPreviewTextViews.remove(key);
mPreviewPlacerView.addView( if (previewTextView != null) {
keyPreview, ViewLayoutUtils.newLayoutParam(mPreviewPlacerView, 0, 0)); return previewTextView;
} }
previewTextView = mFreeKeyPreviewTextViews.poll();
private TextView getKeyPreviewText(final int pointerId) { if (previewTextView != null) {
TextView previewText = mKeyPreviewTexts.get(pointerId); return previewTextView;
if (previewText != null) {
return previewText;
} }
final Context context = getContext(); final Context context = getContext();
if (mKeyPreviewLayoutId != 0) { if (mKeyPreviewLayoutId != 0) {
previewText = (TextView)LayoutInflater.from(context).inflate(mKeyPreviewLayoutId, null); previewTextView = (TextView)LayoutInflater.from(context)
.inflate(mKeyPreviewLayoutId, null);
} else { } else {
previewText = new TextView(context); previewTextView = new TextView(context);
} }
mKeyPreviewTexts.put(pointerId, previewText); locatePreviewPlacerView();
return previewText; mPreviewPlacerView.addView(
previewTextView, ViewLayoutUtils.newLayoutParam(mPreviewPlacerView, 0, 0));
return previewTextView;
} }
private void dismissAllKeyPreviews() { private void dismissAllKeyPreviews() {
final int pointerCount = mKeyPreviewTexts.size(); for (final Key key : new HashSet<Key>(mShowingKeyPreviewTextViews.keySet())) {
for (int id = 0; id < pointerCount; id++) { final TextView previewTextView = mShowingKeyPreviewTextViews.remove(key);
final TextView previewText = mKeyPreviewTexts.get(id); if (previewTextView != null) {
if (previewText != null) { previewTextView.setVisibility(INVISIBLE);
previewText.setVisibility(INVISIBLE); mFreeKeyPreviewTextViews.add(previewTextView);
} }
} }
PointerTracker.setReleasedKeyGraphicsToAllKeys(); PointerTracker.setReleasedKeyGraphicsToAllKeys();
@ -735,23 +740,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
private static final int STATE_HAS_MOREKEYS = 1; private static final int STATE_HAS_MOREKEYS = 1;
@Override @Override
public void showKeyPreview(final PointerTracker tracker) { public void showKeyPreview(final Key key) {
final KeyPreviewDrawParams previewParams = mKeyPreviewDrawParams;
final Keyboard keyboard = getKeyboard();
if (!mShowKeyPreviewPopup) {
previewParams.mPreviewVisibleOffset = -keyboard.mVerticalGap;
return;
}
final TextView previewText = getKeyPreviewText(tracker.mPointerId);
// If the key preview has no parent view yet, add it to the ViewGroup which can place
// key preview absolutely in SoftInputWindow.
if (previewText.getParent() == null) {
addKeyPreview(previewText);
}
mDrawingHandler.cancelDismissKeyPreview(tracker);
final Key key = tracker.getKey();
// If key is invalid or IME is already closed, we must not show key preview. // If key is invalid or IME is already closed, we must not show key preview.
// Trying to show key preview while root window is closed causes // Trying to show key preview while root window is closed causes
// WindowManager.BadTokenException. // WindowManager.BadTokenException.
@ -759,38 +748,47 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
return; return;
} }
final KeyPreviewDrawParams previewParams = mKeyPreviewDrawParams;
final Keyboard keyboard = getKeyboard();
if (!mShowKeyPreviewPopup) {
previewParams.mPreviewVisibleOffset = -keyboard.mVerticalGap;
return;
}
final TextView previewTextView = getKeyPreviewTextView(key);
final KeyDrawParams drawParams = mKeyDrawParams; final KeyDrawParams drawParams = mKeyDrawParams;
previewText.setTextColor(drawParams.mPreviewTextColor); previewTextView.setTextColor(drawParams.mPreviewTextColor);
final Drawable background = previewText.getBackground(); final Drawable background = previewTextView.getBackground();
final String label = key.getPreviewLabel(); final String label = key.getPreviewLabel();
// What we show as preview should match what we show on a key top in onDraw(). // What we show as preview should match what we show on a key top in onDraw().
if (label != null) { if (label != null) {
// TODO Should take care of temporaryShiftLabel here. // TODO Should take care of temporaryShiftLabel here.
previewText.setCompoundDrawables(null, null, null, null); previewTextView.setCompoundDrawables(null, null, null, null);
previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, previewTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
key.selectPreviewTextSize(drawParams)); key.selectPreviewTextSize(drawParams));
previewText.setTypeface(key.selectPreviewTypeface(drawParams)); previewTextView.setTypeface(key.selectPreviewTypeface(drawParams));
previewText.setText(label); previewTextView.setText(label);
} else { } else {
previewText.setCompoundDrawables(null, null, null, previewTextView.setCompoundDrawables(null, null, null,
key.getPreviewIcon(keyboard.mIconsSet)); key.getPreviewIcon(keyboard.mIconsSet));
previewText.setText(null); previewTextView.setText(null);
} }
previewText.measure( previewTextView.measure(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
final int keyDrawWidth = key.getDrawWidth(); final int keyDrawWidth = key.getDrawWidth();
final int previewWidth = previewText.getMeasuredWidth(); final int previewWidth = previewTextView.getMeasuredWidth();
final int previewHeight = mKeyPreviewHeight; final int previewHeight = mKeyPreviewHeight;
// The width and height of visible part of the key preview background. The content marker // The width and height of visible part of the key preview background. The content marker
// of the background 9-patch have to cover the visible part of the background. // of the background 9-patch have to cover the visible part of the background.
previewParams.mPreviewVisibleWidth = previewWidth - previewText.getPaddingLeft() previewParams.mPreviewVisibleWidth = previewWidth - previewTextView.getPaddingLeft()
- previewText.getPaddingRight(); - previewTextView.getPaddingRight();
previewParams.mPreviewVisibleHeight = previewHeight - previewText.getPaddingTop() previewParams.mPreviewVisibleHeight = previewHeight - previewTextView.getPaddingTop()
- previewText.getPaddingBottom(); - previewTextView.getPaddingBottom();
// The distance between the top edge of the parent key and the bottom of the visible part // The distance between the top edge of the parent key and the bottom of the visible part
// of the key preview background. // of the key preview background.
previewParams.mPreviewVisibleOffset = mKeyPreviewOffset - previewText.getPaddingBottom(); previewParams.mPreviewVisibleOffset =
mKeyPreviewOffset - previewTextView.getPaddingBottom();
getLocationInWindow(mOriginCoords); getLocationInWindow(mOriginCoords);
// The key preview is horizontally aligned with the center of the visible part of the // The key preview is horizontally aligned with the center of the visible part of the
// parent key. If it doesn't fit in this {@link KeyboardView}, it is moved inward to fit and // parent key. If it doesn't fit in this {@link KeyboardView}, it is moved inward to fit and
@ -817,13 +815,14 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
background.setState(KEY_PREVIEW_BACKGROUND_STATE_TABLE[statePosition][hasMoreKeys]); background.setState(KEY_PREVIEW_BACKGROUND_STATE_TABLE[statePosition][hasMoreKeys]);
} }
ViewLayoutUtils.placeViewAt( ViewLayoutUtils.placeViewAt(
previewText, previewX, previewY, previewWidth, previewHeight); previewTextView, previewX, previewY, previewWidth, previewHeight);
previewText.setVisibility(VISIBLE); previewTextView.setVisibility(VISIBLE);
mShowingKeyPreviewTextViews.put(key, previewTextView);
} }
@Override @Override
public void dismissKeyPreview(final PointerTracker tracker) { public void dismissKeyPreview(final Key key) {
mDrawingHandler.dismissKeyPreview(mKeyPreviewLingerTimeout, tracker); mDrawingHandler.dismissKeyPreview(mKeyPreviewLingerTimeout, key);
} }
public void setSlidingKeyInputPreviewEnabled(final boolean enabled) { public void setSlidingKeyInputPreviewEnabled(final boolean enabled) {

View File

@ -84,8 +84,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
public interface DrawingProxy { public interface DrawingProxy {
public void invalidateKey(Key key); public void invalidateKey(Key key);
public void showKeyPreview(PointerTracker tracker); public void showKeyPreview(Key key);
public void dismissKeyPreview(PointerTracker tracker); public void dismissKeyPreview(Key key);
public void showSlidingKeyInputPreview(PointerTracker tracker); public void showSlidingKeyInputPreview(PointerTracker tracker);
public void dismissSlidingKeyInputPreview(); public void dismissSlidingKeyInputPreview();
public void showGestureTrail(PointerTracker tracker, boolean showsFloatingPreviewText); public void showGestureTrail(PointerTracker tracker, boolean showsFloatingPreviewText);
@ -637,7 +637,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
} }
private void setReleasedKeyGraphics(final Key key) { private void setReleasedKeyGraphics(final Key key) {
mDrawingProxy.dismissKeyPreview(this); mDrawingProxy.dismissKeyPreview(key);
if (key == null) { if (key == null) {
return; return;
} }
@ -685,7 +685,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
} }
if (!key.noKeyPreview() && !sInGesture && !needsToSuppressKeyPreviewPopup(eventTime)) { if (!key.noKeyPreview() && !sInGesture && !needsToSuppressKeyPreviewPopup(eventTime)) {
mDrawingProxy.showKeyPreview(this); mDrawingProxy.showKeyPreview(key);
} }
updatePressKeyGraphics(key); updatePressKeyGraphics(key);