diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index 992282bf9..db1691709 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -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; } diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java index b9ce4fb1f..7d7eedb17 100644 --- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java @@ -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 mMoreKeysPanelCache = new WeakHashMap(); @@ -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(); } /** diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java index a698b0bd8..16606a1c5 100644 --- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java @@ -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); + } } diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java b/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java index f9a196d24..8bcddccf3 100644 --- a/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java +++ b/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java @@ -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(); } diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index 20a299e49..a44f3ede0 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -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 { diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 305f38d8c..dcbbfca09 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -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 diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java index 8cc09f39b..f0017c095 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java +++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java @@ -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); + } } diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java index e7cb97fc2..9fc2bf987 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java @@ -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 mWords = CollectionUtils.newArrayList(); private final ArrayList 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();