| Index: content/public/android/java/src/org/chromium/content/browser/input/PopupTouchHandleDrawable.java
|
| diff --git a/content/public/android/java/src/org/chromium/content/browser/input/PopupTouchHandleDrawable.java b/content/public/android/java/src/org/chromium/content/browser/input/PopupTouchHandleDrawable.java
|
| index 720534c628e6c35b71cb89f5870c755ce41a07f1..f9680dd79ec393880bff42db8696c48cec3961e8 100644
|
| --- a/content/public/android/java/src/org/chromium/content/browser/input/PopupTouchHandleDrawable.java
|
| +++ b/content/public/android/java/src/org/chromium/content/browser/input/PopupTouchHandleDrawable.java
|
| @@ -8,6 +8,7 @@ import android.annotation.SuppressLint;
|
| import android.content.Context;
|
| import android.graphics.Canvas;
|
| import android.graphics.drawable.Drawable;
|
| +import android.graphics.drawable.LayerDrawable;
|
| import android.view.MotionEvent;
|
| import android.view.View;
|
| import android.view.animation.AnimationUtils;
|
| @@ -29,7 +30,7 @@ import java.lang.ref.WeakReference;
|
| */
|
| @JNINamespace("content")
|
| public class PopupTouchHandleDrawable extends View {
|
| - private Drawable mDrawable;
|
| + private InvertedDrawable mDrawable;
|
| private final PopupWindow mContainer;
|
| private final Context mContext;
|
| private final PositionObserver.Listener mParentPositionListener;
|
| @@ -111,6 +112,7 @@ public class PopupTouchHandleDrawable extends View {
|
| mContainer.setAnimationStyle(0);
|
| mAlpha = 1.f;
|
| mVisible = getVisibility() == VISIBLE;
|
| + mDrawable = getHandleDrawable(false, false);
|
| mParentPositionListener = new PositionObserver.Listener() {
|
| @Override
|
| public void onPositionChanged(int x, int y) {
|
| @@ -142,32 +144,40 @@ public class PopupTouchHandleDrawable extends View {
|
| }
|
|
|
| @CalledByNative
|
| - private void setOrientation(int orientation) {
|
| + private void setOrientation(int orientation, boolean mirrorVertical, boolean mirrorHorizontal,
|
| + boolean mirrorChanged) {
|
| assert (orientation >= TouchHandleOrientation.LEFT
|
| && orientation <= TouchHandleOrientation.UNDEFINED);
|
| - if (mOrientation == orientation) return;
|
|
|
| final boolean hadValidOrientation = mOrientation != TouchHandleOrientation.UNDEFINED;
|
| + final boolean orientationChanged = mOrientation != orientation;
|
| mOrientation = orientation;
|
|
|
| final int oldAdjustedPositionX = getAdjustedPositionX();
|
| final int oldAdjustedPositionY = getAdjustedPositionY();
|
|
|
| + // Create new InvertedDrawable only if orientation has changed.
|
| + // Otherwise, change the mirror values to scale canvas on draw() calls.
|
| + if (orientationChanged) {
|
| + mDrawable = getHandleDrawable(mirrorVertical, mirrorHorizontal);
|
| + } else if (mirrorChanged) {
|
| + mDrawable.setMirrorParams(mirrorVertical, mirrorHorizontal);
|
| + }
|
| +
|
| switch (orientation) {
|
| case TouchHandleOrientation.LEFT: {
|
| - mDrawable = HandleViewResources.getLeftHandleDrawable(mContext);
|
| - mHotspotX = (mDrawable.getIntrinsicWidth() * 3) / 4f;
|
| + int drawableWidth = mDrawable.getIntrinsicWidth();
|
| + mHotspotX = mirrorHorizontal ? drawableWidth / 4f : (drawableWidth * 3) / 4f;
|
| break;
|
| }
|
|
|
| case TouchHandleOrientation.RIGHT: {
|
| - mDrawable = HandleViewResources.getRightHandleDrawable(mContext);
|
| - mHotspotX = mDrawable.getIntrinsicWidth() / 4f;
|
| + int drawableWidth = mDrawable.getIntrinsicWidth();
|
| + mHotspotX = mirrorHorizontal ? (drawableWidth * 3) / 4f : drawableWidth / 4f;
|
| break;
|
| }
|
|
|
| case TouchHandleOrientation.CENTER: {
|
| - mDrawable = HandleViewResources.getCenterHandleDrawable(mContext);
|
| mHotspotX = mDrawable.getIntrinsicWidth() / 2f;
|
| break;
|
| }
|
| @@ -176,7 +186,8 @@ public class PopupTouchHandleDrawable extends View {
|
| default:
|
| break;
|
| }
|
| - mHotspotY = 0;
|
| +
|
| + mHotspotY = mirrorVertical ? mDrawable.getIntrinsicHeight() : 0;
|
|
|
| // Force handle repositioning to accommodate the new orientation's hotspot.
|
| if (hadValidOrientation) setFocus(oldAdjustedPositionX, oldAdjustedPositionY);
|
| @@ -184,6 +195,38 @@ public class PopupTouchHandleDrawable extends View {
|
| scheduleInvalidate();
|
| }
|
|
|
| + private InvertedDrawable getHandleDrawable(boolean mirrorVertical, boolean mirrorHorizontal) {
|
| + final Drawable drawable;
|
| +
|
| + switch (mOrientation) {
|
| + case TouchHandleOrientation.LEFT: {
|
| + drawable = HandleViewResources.getLeftHandleDrawable(mContext);
|
| + break;
|
| + }
|
| +
|
| + case TouchHandleOrientation.RIGHT: {
|
| + drawable = HandleViewResources.getRightHandleDrawable(mContext);
|
| + break;
|
| + }
|
| +
|
| + case TouchHandleOrientation.CENTER: {
|
| + drawable = HandleViewResources.getCenterHandleDrawable(mContext);
|
| + break;
|
| + }
|
| +
|
| + case TouchHandleOrientation.UNDEFINED:
|
| + default:
|
| + drawable = HandleViewResources.getCenterHandleDrawable(mContext);
|
| + break;
|
| + }
|
| +
|
| + Drawable[] drawableArray = {drawable};
|
| +
|
| + // TODO(AviD): Need to avoid creating new InvertedDrawable for every orientation change.
|
| + // Update this once there is a better way to get the inverted handles.
|
| + return new InvertedDrawable(drawableArray, mirrorVertical, mirrorHorizontal);
|
| + }
|
| +
|
| private void updateParentPosition(int parentPositionX, int parentPositionY) {
|
| if (mParentPositionX == parentPositionX && mParentPositionY == parentPositionY) return;
|
| mParentPositionX = parentPositionX;
|
| @@ -388,4 +431,31 @@ public class PopupTouchHandleDrawable extends View {
|
| if (mDrawable == null) return 0;
|
| return mDrawable.getIntrinsicHeight();
|
| }
|
| +
|
| + private class InvertedDrawable extends LayerDrawable {
|
| + final Drawable mDrawable;
|
| + float mScaleX;
|
| + float mScaleY;
|
| +
|
| + InvertedDrawable(
|
| + Drawable[] drawableArray, boolean mirrorVertical, boolean mirrorHorizontal) {
|
| + super(drawableArray);
|
| + setMirrorParams(mirrorVertical, mirrorHorizontal);
|
| + mDrawable = drawableArray[0];
|
| + }
|
| +
|
| + void setMirrorParams(boolean mirrorVertical, boolean mirrorHorizontal) {
|
| + mScaleX = mirrorHorizontal ? -1.f : 1.f;
|
| + mScaleY = mirrorVertical ? -1.f : 1.f;
|
| + }
|
| +
|
| + @Override
|
| + public void draw(final Canvas canvas) {
|
| + canvas.save();
|
| + canvas.scale(mScaleX, mScaleY, mDrawable.getBounds().width() / 2,
|
| + mDrawable.getBounds().height() / 2);
|
| + super.draw(canvas);
|
| + canvas.restore();
|
| + }
|
| + }
|
| }
|
|
|