Merge "Refactor more keys menu framework (part 1)"

This commit is contained in:
Tom Ouyang 2012-12-07 17:32:19 -08:00 committed by Android (Google) Code Review
commit b6e398a71d
8 changed files with 136 additions and 98 deletions

View file

@ -102,7 +102,8 @@ import java.util.HashSet;
* @attr ref R.styleable#Keyboard_Key_keyShiftedLetterHintActivatedColor
* @attr ref R.styleable#Keyboard_Key_keyPreviewTextColor
*/
public class KeyboardView extends View implements PointerTracker.DrawingProxy {
public class KeyboardView extends View implements PointerTracker.DrawingProxy,
MoreKeysPanel.Controller {
private static final String TAG = KeyboardView.class.getSimpleName();
// XML attributes
@ -137,6 +138,10 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
private final PreviewPlacerView mPreviewPlacerView;
private final int[] mOriginCoords = CoordinateUtils.newInstance();
// More keys panel (used by both more keys keyboard and more suggestions view)
// TODO: Consider extending to support multiple more keys panels
protected MoreKeysPanel mMoreKeysPanel;
// Key preview
private static final int PREVIEW_ALPHA = 240;
private final int mKeyPreviewLayoutId;
@ -1013,8 +1018,34 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
requestLayout();
}
@Override
public void onShowMoreKeysPanel(final MoreKeysPanel panel) {
if (isShowingMoreKeysPanel()) {
onDismissMoreKeysPanel();
}
mMoreKeysPanel = panel;
mPreviewPlacerView.addView(mMoreKeysPanel.getContainerView());
}
public boolean isShowingMoreKeysPanel() {
return (mMoreKeysPanel != null);
}
@Override
public boolean dismissMoreKeysPanel() {
if (isShowingMoreKeysPanel()) {
return mMoreKeysPanel.dismissMoreKeysPanel();
}
return false;
}
@Override
public boolean onDismissMoreKeysPanel() {
if (isShowingMoreKeysPanel()) {
mPreviewPlacerView.removeView(mMoreKeysPanel.getContainerView());
mMoreKeysPanel = null;
return true;
}
return false;
}

View file

@ -39,7 +39,6 @@ import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodSubtype;
import android.widget.PopupWindow;
import com.android.inputmethod.accessibility.AccessibilityUtils;
import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
@ -136,8 +135,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
private int mAltCodeKeyWhileTypingAnimAlpha = Constants.Color.ALPHA_OPAQUE;
// More keys keyboard
private PopupWindow mMoreKeysWindow;
private MoreKeysPanel mMoreKeysPanel;
private int mMoreKeysPanelPointerTrackerId;
private final WeakHashMap<Key, MoreKeysPanel> mMoreKeysPanelCache =
new WeakHashMap<Key, MoreKeysPanel>();
@ -665,12 +662,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
}
mMoreKeysPanelCache.put(parentKey, moreKeysPanel);
}
if (mMoreKeysWindow == null) {
mMoreKeysWindow = new PopupWindow(getContext());
mMoreKeysWindow.setBackgroundDrawable(null);
mMoreKeysWindow.setAnimationStyle(R.style.MoreKeysKeyboardAnimation);
}
mMoreKeysPanel = moreKeysPanel;
mMoreKeysPanelPointerTrackerId = tracker.mPointerId;
final int[] lastCoords = CoordinateUtils.newInstance();
@ -688,12 +679,11 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
// {@code mPreviewVisibleOffset} has been set appropriately in
// {@link KeyboardView#showKeyPreview(PointerTracker)}.
final int pointY = parentKey.mY + mKeyPreviewDrawParams.mPreviewVisibleOffset;
moreKeysPanel.showMoreKeysPanel(
this, this, pointX, pointY, mMoreKeysWindow, mKeyboardActionListener);
moreKeysPanel.showMoreKeysPanel(this, this, pointX, pointY, mKeyboardActionListener);
final int translatedX = moreKeysPanel.translateX(CoordinateUtils.x(lastCoords));
final int translatedY = moreKeysPanel.translateY(CoordinateUtils.y(lastCoords));
tracker.onShowMoreKeysPanel(translatedX, translatedY, moreKeysPanel);
dimEntireKeyboard(true);
dimEntireKeyboard(true /* dimmed */);
return true;
}
@ -876,15 +866,10 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
}
@Override
public boolean dismissMoreKeysPanel() {
if (mMoreKeysWindow == null || !mMoreKeysWindow.isShowing()) {
return false;
}
mMoreKeysWindow.dismiss();
mMoreKeysPanel = null;
public boolean onDismissMoreKeysPanel() {
mMoreKeysPanelPointerTrackerId = -1;
dimEntireKeyboard(false);
return true;
dimEntireKeyboard(false /* dimmed */);
return super.onDismissMoreKeysPanel();
}
/**

View file

@ -19,9 +19,7 @@ package com.android.inputmethod.keyboard;
import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.PopupWindow;
import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy;
import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
@ -154,37 +152,33 @@ public final class MoreKeysKeyboardView extends KeyboardView implements MoreKeys
@Override
public void showMoreKeysPanel(final View parentView, final Controller controller,
final int pointX, final int pointY, final PopupWindow window,
final KeyboardActionListener listener) {
final int pointX, final int pointY, final KeyboardActionListener listener) {
mController = controller;
mListener = listener;
final View container = (View)getParent();
final View container = getContainerView();
final MoreKeysKeyboard pane = (MoreKeysKeyboard)getKeyboard();
final int defaultCoordX = pane.getDefaultCoordX();
// The coordinates of panel's left-top corner in parentView's coordinate system.
final int x = pointX - defaultCoordX - container.getPaddingLeft();
final int y = pointY - container.getMeasuredHeight() + container.getPaddingBottom();
window.setContentView(container);
window.setWidth(container.getMeasuredWidth());
window.setHeight(container.getMeasuredHeight());
parentView.getLocationInWindow(mCoordinates);
window.showAtLocation(parentView, Gravity.NO_GRAVITY,
x + CoordinateUtils.x(mCoordinates), y + CoordinateUtils.y(mCoordinates));
// Ensure the horizontal position of the panel does not extend past the screen edges.
final int maxX = parentView.getMeasuredWidth() - container.getMeasuredWidth();
final int panelX = Math.max(0, Math.min(maxX, x + CoordinateUtils.x(mCoordinates)));
final int panelY = y + CoordinateUtils.y(mCoordinates);
container.setX(panelX);
container.setY(panelY);
mOriginX = x + container.getPaddingLeft();
mOriginY = y + container.getPaddingTop();
controller.onShowMoreKeysPanel(this);
}
private boolean mIsDismissing;
@Override
public boolean dismissMoreKeysPanel() {
if (mIsDismissing || mController == null) return false;
mIsDismissing = true;
final boolean dismissed = mController.dismissMoreKeysPanel();
mIsDismissing = false;
return dismissed;
if (mController == null) return false;
return mController.onDismissMoreKeysPanel();
}
@Override
@ -196,4 +190,14 @@ public final class MoreKeysKeyboardView extends KeyboardView implements MoreKeys
public int translateY(final int y) {
return y - mOriginY;
}
@Override
public View getContainerView() {
return (View)getParent();
}
@Override
public boolean isShowingInParent() {
return (getContainerView().getParent() != null);
}
}

View file

@ -17,25 +17,42 @@
package com.android.inputmethod.keyboard;
import android.view.View;
import android.widget.PopupWindow;
public interface MoreKeysPanel extends PointerTracker.KeyEventHandler {
public interface Controller {
public boolean dismissMoreKeysPanel();
/**
* Add the {@link MoreKeysPanel} to the target view.
* @param panel
*/
public void onShowMoreKeysPanel(final MoreKeysPanel panel);
/**
* Remove the current {@link MoreKeysPanel} to the target view.
*/
public boolean onDismissMoreKeysPanel();
}
/**
* Show more keys panel.
* Initializes the layout and event handling of this {@link MoreKeysPanel} and calls the
* controller's onShowMoreKeysPanel to add the panel's container view.
*
* @param parentView the parent view of this more keys panel
* @param controller the controller that can dismiss this more keys panel
* @param pointX x coordinate of this more keys panel
* @param pointY y coordinate of this more keys panel
* @param window PopupWindow to be used to show this more keys panel
* @param listener the listener that will receive keyboard action from this more keys panel.
* @param parentView the parent view of this {@link MoreKeysPanel}
* @param controller the controller that can dismiss this {@link MoreKeysPanel}
* @param pointX x coordinate of this {@link MoreKeysPanel}
* @param pointY y coordinate of this {@link MoreKeysPanel}
* @param listener the listener that will receive keyboard action from this
* {@link MoreKeysPanel}.
*/
public void showMoreKeysPanel(View parentView, Controller controller, int pointX, int pointY,
PopupWindow window, KeyboardActionListener listener);
// TODO: Currently the MoreKeysPanel is inside a container view that is added to the parent.
// Consider the simpler approach of placing the MoreKeysPanel itself into the parent view.
public void showMoreKeysPanel(View parentView, Controller controller, int pointX,
int pointY, KeyboardActionListener listener);
/**
* Dismisses the more keys panel and calls the controller's onDismissMoreKeysPanel to remove
* the panel's container view.
*/
public boolean dismissMoreKeysPanel();
/**
* Translate X-coordinate of touch event to the local X-coordinate of this
@ -54,4 +71,14 @@ public interface MoreKeysPanel extends PointerTracker.KeyEventHandler {
* @return the local Y-coordinate to this {@link MoreKeysPanel}
*/
public int translateY(int y);
/**
* Return the view containing the more keys panel.
*/
public View getContainerView();
/**
* Return whether the panel is currently being shown.
*/
public boolean isShowingInParent();
}

View file

@ -77,13 +77,14 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
public TimerProxy getTimerProxy();
}
public interface DrawingProxy extends MoreKeysPanel.Controller {
public interface DrawingProxy {
public void invalidateKey(Key key);
public void showKeyPreview(PointerTracker tracker);
public void dismissKeyPreview(PointerTracker tracker);
public void showSlidingKeyInputPreview(PointerTracker tracker);
public void dismissSlidingKeyInputPreview();
public void showGesturePreviewTrail(PointerTracker tracker, boolean isOldestTracker);
public boolean dismissMoreKeysPanel();
}
public interface TimerProxy {

View file

@ -1064,12 +1064,13 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
final int suggestionsHeight = (mSuggestionsContainer.getVisibility() == View.GONE) ? 0
: mSuggestionsContainer.getHeight();
final int extraHeight = extractHeight + backingHeight + suggestionsHeight;
int touchY = extraHeight;
int visibleTopY = extraHeight;
// Need to set touchable region only if input view is being shown
if (mainKeyboardView.isShown()) {
if (mSuggestionsContainer.getVisibility() == View.VISIBLE) {
touchY -= suggestionsHeight;
visibleTopY -= suggestionsHeight;
}
final int touchY = mainKeyboardView.isShowingMoreKeysPanel() ? 0 : visibleTopY;
final int touchWidth = mainKeyboardView.getWidth();
final int touchHeight = mainKeyboardView.getHeight() + extraHeight
// Extend touchable region below the keyboard.
@ -1077,8 +1078,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION;
outInsets.touchableRegion.set(0, touchY, touchWidth, touchHeight);
}
outInsets.contentTopInsets = touchY;
outInsets.visibleTopInsets = touchY;
outInsets.contentTopInsets = visibleTopY;
outInsets.visibleTopInsets = visibleTopY;
}
@Override

View file

@ -19,10 +19,8 @@ package com.android.inputmethod.latin.suggestions;
import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.PopupWindow;
import com.android.inputmethod.keyboard.KeyDetector;
import com.android.inputmethod.keyboard.Keyboard;
@ -148,37 +146,33 @@ public final class MoreSuggestionsView extends KeyboardView implements MoreKeysP
@Override
public void showMoreKeysPanel(final View parentView, final Controller controller,
final int pointX, final int pointY, final PopupWindow window,
final KeyboardActionListener listener) {
final int pointX, final int pointY, final KeyboardActionListener listener) {
mController = controller;
mListener = listener;
final View container = (View)getParent();
final View container = getContainerView();
final MoreSuggestions pane = (MoreSuggestions)getKeyboard();
final int defaultCoordX = pane.mOccupiedWidth / 2;
// The coordinates of panel's left-top corner in parentView's coordinate system.
final int x = pointX - defaultCoordX - container.getPaddingLeft();
final int y = pointY - container.getMeasuredHeight() + container.getPaddingBottom();
window.setContentView(container);
window.setWidth(container.getMeasuredWidth());
window.setHeight(container.getMeasuredHeight());
parentView.getLocationInWindow(mCoordinates);
window.showAtLocation(parentView, Gravity.NO_GRAVITY,
x + CoordinateUtils.x(mCoordinates), y + CoordinateUtils.y(mCoordinates));
// Ensure the horizontal position of the panel does not extend past the screen edges.
final int maxX = parentView.getMeasuredWidth() - container.getMeasuredWidth();
final int panelX = Math.max(0, Math.min(maxX, x + CoordinateUtils.x(mCoordinates)));
final int panelY = y + CoordinateUtils.y(mCoordinates);
container.setX(panelX);
container.setY(panelY);
mOriginX = x + container.getPaddingLeft();
mOriginY = y + container.getPaddingTop();
controller.onShowMoreKeysPanel(this);
}
private boolean mIsDismissing;
@Override
public boolean dismissMoreKeysPanel() {
if (mIsDismissing || mController == null) return false;
mIsDismissing = true;
final boolean dismissed = mController.dismissMoreKeysPanel();
mIsDismissing = false;
return dismissed;
if (mController == null) return false;
return mController.onDismissMoreKeysPanel();
}
@Override
@ -225,4 +219,14 @@ public final class MoreSuggestionsView extends KeyboardView implements MoreKeysP
tracker.processMotionEvent(action, x, y, eventTime, mModalPanelKeyEventHandler);
return true;
}
@Override
public View getContainerView() {
return (View)getParent();
}
@Override
public boolean isShowingInParent() {
return (getContainerView().getParent() != null);
}
}

View file

@ -27,7 +27,6 @@ import android.graphics.Paint.Align;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Message;
import android.text.Spannable;
@ -91,7 +90,6 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
private final View mMoreSuggestionsContainer;
private final MoreSuggestionsView mMoreSuggestionsView;
private final MoreSuggestions.Builder mMoreSuggestionsBuilder;
private final PopupWindow mMoreSuggestionsWindow;
private final ArrayList<TextView> mWords = CollectionUtils.newArrayList();
private final ArrayList<TextView> mInfos = CollectionUtils.newArrayList();
@ -641,21 +639,6 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
.findViewById(R.id.more_suggestions_view);
mMoreSuggestionsBuilder = new MoreSuggestions.Builder(mMoreSuggestionsView);
final PopupWindow moreWindow = new PopupWindow(context);
moreWindow.setWindowLayoutMode(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
moreWindow.setBackgroundDrawable(new ColorDrawable(android.R.color.transparent));
moreWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
moreWindow.setFocusable(true);
moreWindow.setOutsideTouchable(true);
moreWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
mKeyboardView.dimEntireKeyboard(false);
}
});
mMoreSuggestionsWindow = moreWindow;
final Resources res = context.getResources();
mMoreSuggestionsModalTolerance = res.getDimensionPixelOffset(
R.dimen.more_suggestions_modal_tolerance);
@ -738,17 +721,19 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
private final MoreKeysPanel.Controller mMoreSuggestionsController =
new MoreKeysPanel.Controller() {
@Override
public boolean dismissMoreKeysPanel() {
return dismissMoreSuggestions();
public boolean onDismissMoreKeysPanel() {
mKeyboardView.dimEntireKeyboard(false /* dimmed */);
return mKeyboardView.onDismissMoreKeysPanel();
}
@Override
public void onShowMoreKeysPanel(MoreKeysPanel panel) {
mKeyboardView.onShowMoreKeysPanel(panel);
}
};
boolean dismissMoreSuggestions() {
if (mMoreSuggestionsWindow.isShowing()) {
mMoreSuggestionsWindow.dismiss();
return true;
}
return false;
return mMoreSuggestionsView.dismissMoreKeysPanel();
}
@Override
@ -780,11 +765,11 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
final int pointX = stripWidth / 2;
final int pointY = -params.mMoreSuggestionsBottomGap;
moreKeysPanel.showMoreKeysPanel(this, mMoreSuggestionsController, pointX, pointY,
mMoreSuggestionsWindow, mMoreSuggestionsListener);
mMoreSuggestionsListener);
mMoreSuggestionsMode = MORE_SUGGESTIONS_CHECKING_MODAL_OR_SLIDING;
mOriginX = mLastX;
mOriginY = mLastY;
mKeyboardView.dimEntireKeyboard(true);
mKeyboardView.dimEntireKeyboard(true /* dimmed */);
for (int i = 0; i < params.mSuggestionsCountInStrip; i++) {
mWords.get(i).setPressed(false);
}
@ -816,7 +801,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
@Override
public boolean dispatchTouchEvent(final MotionEvent me) {
if (!mMoreSuggestionsWindow.isShowing()
if (!mMoreSuggestionsView.isShowingInParent()
|| mMoreSuggestionsMode == MORE_SUGGESTIONS_IN_MODAL_MODE) {
mLastX = (int)me.getX();
mLastY = (int)me.getY();