Merge changes from topic "magnifier_expose_size_and_zoom-pi-dev" into pi-dev
* changes: [Magnifier-31] Do not magnify outside current line [Magnifier-29] Expose size and zoom in the API
This commit is contained in:
@@ -53398,6 +53398,9 @@ package android.widget {
|
||||
public final class Magnifier {
|
||||
ctor public Magnifier(android.view.View);
|
||||
method public void dismiss();
|
||||
method public int getHeight();
|
||||
method public int getWidth();
|
||||
method public float getZoom();
|
||||
method public void show(float, float);
|
||||
method public void update();
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import android.graphics.Color;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
@@ -4648,10 +4649,14 @@ public class Editor {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected final void showMagnifier(@NonNull final MotionEvent event) {
|
||||
if (mMagnifier == null) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Computes the position where the magnifier should be shown, relative to
|
||||
* {@code mTextView}, and writes them to {@code showPosInView}. Also decides
|
||||
* whether the magnifier should be shown or dismissed after this touch event.
|
||||
* @return Whether the magnifier should be shown at the computed coordinates or dismissed.
|
||||
*/
|
||||
private boolean obtainMagnifierShowCoordinates(@NonNull final MotionEvent event,
|
||||
final PointF showPosInView) {
|
||||
|
||||
final int trigger = getMagnifierHandleTrigger();
|
||||
final int offset;
|
||||
@@ -4669,26 +4674,52 @@ public class Editor {
|
||||
}
|
||||
|
||||
if (offset == -1) {
|
||||
dismissMagnifier();
|
||||
return false;
|
||||
}
|
||||
|
||||
final Layout layout = mTextView.getLayout();
|
||||
final int lineNumber = layout.getLineForOffset(offset);
|
||||
// Horizontally move the magnifier smoothly.
|
||||
|
||||
// Horizontally move the magnifier smoothly but clamp inside the current line.
|
||||
final int[] textViewLocationOnScreen = new int[2];
|
||||
mTextView.getLocationOnScreen(textViewLocationOnScreen);
|
||||
final float xPosInView = event.getRawX() - textViewLocationOnScreen[0];
|
||||
final float touchXInView = event.getRawX() - textViewLocationOnScreen[0];
|
||||
final float lineLeft = mTextView.getLayout().getLineLeft(lineNumber)
|
||||
+ mTextView.getTotalPaddingLeft() - mTextView.getScrollX();
|
||||
final float lineRight = mTextView.getLayout().getLineRight(lineNumber)
|
||||
+ mTextView.getTotalPaddingLeft() - mTextView.getScrollX();
|
||||
final float contentWidth = Math.round(mMagnifier.getWidth() / mMagnifier.getZoom());
|
||||
if (touchXInView < lineLeft - contentWidth / 2
|
||||
|| touchXInView > lineRight + contentWidth / 2) {
|
||||
// The touch is too out of the bounds of the current line, so hide the magnifier.
|
||||
return false;
|
||||
}
|
||||
showPosInView.x = Math.max(lineLeft, Math.min(lineRight, touchXInView));
|
||||
|
||||
// Vertically snap to middle of current line.
|
||||
final float yPosInView = (mTextView.getLayout().getLineTop(lineNumber)
|
||||
showPosInView.y = (mTextView.getLayout().getLineTop(lineNumber)
|
||||
+ mTextView.getLayout().getLineBottom(lineNumber)) / 2.0f
|
||||
+ mTextView.getTotalPaddingTop() - mTextView.getScrollY();
|
||||
|
||||
// Make the cursor visible and stop blinking.
|
||||
mRenderCursorRegardlessTiming = true;
|
||||
mTextView.invalidateCursorPath();
|
||||
suspendBlink();
|
||||
return true;
|
||||
}
|
||||
|
||||
mMagnifier.show(xPosInView, yPosInView);
|
||||
protected final void updateMagnifier(@NonNull final MotionEvent event) {
|
||||
if (mMagnifier == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final PointF showPosInView = new PointF();
|
||||
final boolean shouldShow = obtainMagnifierShowCoordinates(event, showPosInView);
|
||||
if (shouldShow) {
|
||||
// Make the cursor visible and stop blinking.
|
||||
mRenderCursorRegardlessTiming = true;
|
||||
mTextView.invalidateCursorPath();
|
||||
suspendBlink();
|
||||
mMagnifier.show(showPosInView.x, showPosInView.y);
|
||||
} else {
|
||||
dismissMagnifier();
|
||||
}
|
||||
}
|
||||
|
||||
protected final void dismissMagnifier() {
|
||||
@@ -4877,11 +4908,11 @@ public class Editor {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mDownPositionX = ev.getRawX();
|
||||
mDownPositionY = ev.getRawY();
|
||||
showMagnifier(ev);
|
||||
updateMagnifier(ev);
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
showMagnifier(ev);
|
||||
updateMagnifier(ev);
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
@@ -5235,11 +5266,11 @@ public class Editor {
|
||||
// re-engages the handle.
|
||||
mTouchWordDelta = 0.0f;
|
||||
mPrevX = UNSET_X_VALUE;
|
||||
showMagnifier(event);
|
||||
updateMagnifier(event);
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
showMagnifier(event);
|
||||
updateMagnifier(event);
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
|
||||
@@ -75,6 +75,8 @@ public final class Magnifier {
|
||||
private final int mWindowWidth;
|
||||
// The height of the window containing the magnifier.
|
||||
private final int mWindowHeight;
|
||||
// The zoom applied to the view region copied to the magnifier window.
|
||||
private final float mZoom;
|
||||
// The width of the bitmaps where the magnifier content is copied.
|
||||
private final int mBitmapWidth;
|
||||
// The height of the bitmaps where the magnifier content is copied.
|
||||
@@ -111,10 +113,10 @@ public final class Magnifier {
|
||||
com.android.internal.R.dimen.magnifier_height);
|
||||
mWindowElevation = context.getResources().getDimension(
|
||||
com.android.internal.R.dimen.magnifier_elevation);
|
||||
final float zoomScale = context.getResources().getFloat(
|
||||
mZoom = context.getResources().getFloat(
|
||||
com.android.internal.R.dimen.magnifier_zoom_scale);
|
||||
mBitmapWidth = Math.round(mWindowWidth / zoomScale);
|
||||
mBitmapHeight = Math.round(mWindowHeight / zoomScale);
|
||||
mBitmapWidth = Math.round(mWindowWidth / mZoom);
|
||||
mBitmapHeight = Math.round(mWindowHeight / mZoom);
|
||||
// The view's surface coordinates will not be updated until the magnifier is first shown.
|
||||
mViewCoordinatesInSurface = new int[2];
|
||||
}
|
||||
@@ -187,21 +189,6 @@ public final class Magnifier {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Surface getValidViewSurface() {
|
||||
// TODO: deduplicate this against the first part of #performPixelCopy
|
||||
final Surface surface;
|
||||
if (mView instanceof SurfaceView) {
|
||||
surface = ((SurfaceView) mView).getHolder().getSurface();
|
||||
} else if (mView.getViewRootImpl() != null) {
|
||||
surface = mView.getViewRootImpl().mSurface;
|
||||
} else {
|
||||
surface = null;
|
||||
}
|
||||
|
||||
return (surface != null && surface.isValid()) ? surface : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismisses the magnifier from the screen. Calling this on a dismissed magnifier is a no-op.
|
||||
*/
|
||||
@@ -226,6 +213,44 @@ public final class Magnifier {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The width of the magnifier window, in pixels.
|
||||
*/
|
||||
public int getWidth() {
|
||||
return mWindowWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The height of the magnifier window, in pixels.
|
||||
*/
|
||||
public int getHeight() {
|
||||
return mWindowHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The zoom applied to the magnified view region copied to the magnifier window.
|
||||
* If the zoom is x and the magnifier window size is (width, height), the original size
|
||||
* of the content copied in the magnifier will be (width / x, height / x).
|
||||
*/
|
||||
public float getZoom() {
|
||||
return mZoom;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Surface getValidViewSurface() {
|
||||
// TODO: deduplicate this against the first part of #performPixelCopy
|
||||
final Surface surface;
|
||||
if (mView instanceof SurfaceView) {
|
||||
surface = ((SurfaceView) mView).getHolder().getSurface();
|
||||
} else if (mView.getViewRootImpl() != null) {
|
||||
surface = mView.getViewRootImpl().mSurface;
|
||||
} else {
|
||||
surface = null;
|
||||
}
|
||||
|
||||
return (surface != null && surface.isValid()) ? surface : null;
|
||||
}
|
||||
|
||||
private void configureCoordinates(final float xPosInView, final float yPosInView) {
|
||||
// Compute the coordinates of the center of the content going to be displayed in the
|
||||
// magnifier. These are relative to the surface the content is copied from.
|
||||
@@ -602,7 +627,7 @@ public final class Magnifier {
|
||||
return null;
|
||||
}
|
||||
synchronized (mWindow.mLock) {
|
||||
return mWindow.mBitmap;
|
||||
return Bitmap.createScaledBitmap(mWindow.mBitmap, mWindowWidth, mWindowHeight, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user