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(); |
+ } |
+ } |
} |