Merge "[Magnifier-39] Hide both handles on overlap" into pi-dev
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 6af678b..dac100a 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -39,6 +39,7 @@
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
+import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -4837,14 +4838,48 @@
return true;
}
- private boolean handleOverlapsMagnifier() {
- final int handleY = mContainer.getDecorViewLayoutParams().y;
- final int magnifierBottomWhenAtWindowTop =
- mTextView.getRootWindowInsets().getSystemWindowInsetTop()
- + mMagnifierAnimator.mMagnifier.getHeight();
- return handleY <= magnifierBottomWhenAtWindowTop;
+ private boolean handleOverlapsMagnifier(@NonNull final HandleView handle,
+ @NonNull final Rect magnifierRect) {
+ final PopupWindow window = handle.mContainer;
+ if (!window.hasDecorView()) {
+ return false;
+ }
+ final Rect handleRect = new Rect(
+ window.getDecorViewLayoutParams().x,
+ window.getDecorViewLayoutParams().y,
+ window.getDecorViewLayoutParams().x + window.getContentView().getWidth(),
+ window.getDecorViewLayoutParams().y + window.getContentView().getHeight());
+ return Rect.intersects(handleRect, magnifierRect);
}
+ private @Nullable HandleView getOtherSelectionHandle() {
+ final SelectionModifierCursorController controller = getSelectionController();
+ if (controller == null || !controller.isActive()) {
+ return null;
+ }
+ return controller.mStartHandle != this
+ ? controller.mStartHandle
+ : controller.mEndHandle;
+ }
+
+ private final Magnifier.Callback mHandlesVisibilityCallback = new Magnifier.Callback() {
+ @Override
+ public void onOperationComplete() {
+ final Point magnifierTopLeft = mMagnifierAnimator.mMagnifier.getWindowCoords();
+ if (magnifierTopLeft == null) {
+ return;
+ }
+ final Rect magnifierRect = new Rect(magnifierTopLeft.x, magnifierTopLeft.y,
+ magnifierTopLeft.x + mMagnifierAnimator.mMagnifier.getWidth(),
+ magnifierTopLeft.y + mMagnifierAnimator.mMagnifier.getHeight());
+ setVisible(!handleOverlapsMagnifier(HandleView.this, magnifierRect));
+ final HandleView otherHandle = getOtherSelectionHandle();
+ if (otherHandle != null) {
+ otherHandle.setVisible(!handleOverlapsMagnifier(otherHandle, magnifierRect));
+ }
+ }
+ };
+
protected final void updateMagnifier(@NonNull final MotionEvent event) {
if (mMagnifierAnimator == null) {
return;
@@ -4858,12 +4893,8 @@
mRenderCursorRegardlessTiming = true;
mTextView.invalidateCursorPath();
suspendBlink();
- // Hide handle if it overlaps the magnifier.
- if (handleOverlapsMagnifier()) {
- setVisible(false);
- } else {
- setVisible(true);
- }
+ mMagnifierAnimator.mMagnifier
+ .setOnOperationCompleteCallback(mHandlesVisibilityCallback);
mMagnifierAnimator.show(showPosInView.x, showPosInView.y);
} else {
@@ -4877,6 +4908,10 @@
mRenderCursorRegardlessTiming = false;
resumeBlink();
setVisible(true);
+ final HandleView otherHandle = getOtherSelectionHandle();
+ if (otherHandle != null) {
+ otherHandle.setVisible(true);
+ }
}
}
diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java
index 5eb6699..cb362e6 100644
--- a/core/java/android/widget/Magnifier.java
+++ b/core/java/android/widget/Magnifier.java
@@ -233,6 +233,17 @@
return mZoom;
}
+ /**
+ * @hide
+ */
+ @Nullable
+ public Point getWindowCoords() {
+ if (mWindow == null) {
+ return null;
+ }
+ return new Point(mWindow.mLastDrawContentPositionX, mWindow.mLastDrawContentPositionY);
+ }
+
@Nullable
private Surface getValidViewSurface() {
// TODO: deduplicate this against the first part of #performPixelCopy
@@ -374,8 +385,11 @@
private final Runnable mMagnifierUpdater;
// The handler where the magnifier updater jobs will be post'd.
private final Handler mHandler;
- // The callback to be run after the next draw. Only used for testing.
+ // The callback to be run after the next draw.
private Callback mCallback;
+ // The position of the magnifier content when the last draw was requested.
+ private int mLastDrawContentPositionX;
+ private int mLastDrawContentPositionY;
// Members below describe the state of the magnifier. Reads/writes to them
// have to be synchronized between the UI thread and the thread that handles
@@ -598,6 +612,8 @@
callback = null;
}
+ mLastDrawContentPositionX = mWindowPositionX + mOffsetX;
+ mLastDrawContentPositionY = mWindowPositionY + mOffsetY;
mFrameDrawScheduled = false;
}