[Magnifier-48] Allow on-the-fly zoom update

The CL adds Magnifier#setZoom(float), which allows dynamically changing
the initial zoom applied to the content that will be magnified and
displayed in the magnifier.

Bug: 72211470
Test: manual testing
Test: atest CtsWidgetTestCases:android.widget.cts.MagnifierTest
Change-Id: I1dd01085ef5a1589a3602aefd03223d1451564f5
This commit is contained in:
Mihai Popa
2018-07-19 15:50:43 +01:00
parent c2e0bee9ea
commit beeaf5589d
3 changed files with 47 additions and 7 deletions

View File

@@ -52977,6 +52977,7 @@ package android.widget {
method public int getSourceWidth();
method public int getWidth();
method public float getZoom();
method public void setZoom(float);
method public void show(float, float);
method public void show(float, float, float, float);
method public void update();

View File

@@ -1545,6 +1545,7 @@ package android.widget {
public final class Magnifier {
method public android.graphics.Bitmap getContent();
method public static android.graphics.PointF getMagnifierDefaultSize();
method public android.graphics.Bitmap getOriginalContent();
method public void setOnOperationCompleteCallback(android.widget.Magnifier.Callback);
}

View File

@@ -77,11 +77,13 @@ public final class Magnifier {
// The height of the window containing the magnifier.
private final int mWindowHeight;
// The zoom applied to the view region copied to the magnifier view.
private final float mZoom;
private float mZoom;
// The width of the content that will be copied to the magnifier.
private final int mSourceWidth;
private int mSourceWidth;
// The height of the content that will be copied to the magnifier.
private final int mSourceHeight;
private int mSourceHeight;
// Whether the zoom of the magnifier has changed since last content copy.
private boolean mDirtyZoom;
// The elevation of the window containing the magnifier.
private final float mWindowElevation;
// The corner radius of the window containing the magnifier.
@@ -196,7 +198,8 @@ public final class Magnifier {
final int startX = mClampedCenterZoomCoords.x - mSourceWidth / 2;
final int startY = mClampedCenterZoomCoords.y - mSourceHeight / 2;
if (sourceCenterX != mPrevShowSourceCoords.x || sourceCenterY != mPrevShowSourceCoords.y) {
if (sourceCenterX != mPrevShowSourceCoords.x || sourceCenterY != mPrevShowSourceCoords.y
|| mDirtyZoom) {
if (mWindow == null) {
synchronized (mLock) {
mWindow = new InternalPopupWindow(mView.getContext(), mView.getDisplay(),
@@ -253,9 +256,16 @@ public final class Magnifier {
public void update() {
if (mWindow != null) {
obtainSurfaces();
// Update the content shown in the magnifier.
performPixelCopy(mPrevStartCoordsInSurface.x, mPrevStartCoordsInSurface.y,
false /* update window position */);
if (!mDirtyZoom) {
// Update the content shown in the magnifier.
performPixelCopy(mPrevStartCoordsInSurface.x, mPrevStartCoordsInSurface.y,
false /* update window position */);
} else {
// If the zoom has changed, we cannot use the same top left coordinates
// as before, so just #show again to have them recomputed.
show(mPrevShowSourceCoords.x, mPrevShowSourceCoords.y,
mPrevShowWindowCoords.x, mPrevShowWindowCoords.y);
}
}
}
@@ -297,6 +307,18 @@ public final class Magnifier {
return mSourceHeight;
}
/**
* Sets the zoom to be applied to the chosen content before being copied to the magnifier popup.
* @param zoom the zoom to be set
*/
public void setZoom(@FloatRange(from = 0f) float zoom) {
Preconditions.checkArgumentPositive(zoom, "Zoom should be positive");
mZoom = zoom;
mSourceWidth = Math.round(mWindowWidth / mZoom);
mSourceHeight = Math.round(mWindowHeight / mZoom);
mDirtyZoom = true;
}
/**
* Returns the zoom to be applied to the magnified view region copied to the magnifier.
* If the zoom is x and the magnifier window size is (width, height), the original size
@@ -534,6 +556,7 @@ public final class Magnifier {
sPixelCopyHandlerThread.getThreadHandler());
mPrevStartCoordsInSurface.x = startXInSurface;
mPrevStartCoordsInSurface.y = startYInSurface;
mDirtyZoom = false;
}
/**
@@ -1019,6 +1042,21 @@ public final class Magnifier {
}
}
/**
* @return the content to be magnified, as bitmap
*
* @hide
*/
@TestApi
public @Nullable Bitmap getOriginalContent() {
if (mWindow == null) {
return null;
}
synchronized (mWindow.mLock) {
return Bitmap.createBitmap(mWindow.mBitmap);
}
}
/**
* @return the size of the magnifier window in dp
*