summaryrefslogtreecommitdiff
path: root/core/java/android/widget/Magnifier.java
diff options
context:
space:
mode:
authorMihai Popa <popam@google.com>2018-08-01 14:33:12 +0100
committerMihai Popa <popam@google.com>2018-11-14 14:23:03 +0000
commit1903cab1784372618aade03518ce2dd5298652e3 (patch)
treeb1f47f8ecb3fbc740dc450c8957076323df77123 /core/java/android/widget/Magnifier.java
parent145401596c4ffeee2d62ae28ad2f2db4f5bf7309 (diff)
[Magnifier-53] Add API around outofbounds behavior
The CL adds a public API to enable customizing magnifier's behavior when the coordinates passed to #show would position the magnifier outside the main application window. Bug: 72211470 Test: manual testing Test: atest CtsWidgetTestCases:android.widget.cts.MagnifierTest Change-Id: I9de26e446354d0ad987a4509089fbec4ee5ef7d3
Diffstat (limited to 'core/java/android/widget/Magnifier.java')
-rw-r--r--core/java/android/widget/Magnifier.java44
1 files changed, 44 insertions, 0 deletions
diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java
index 9da2a4307a93..9f509b1f3d0b 100644
--- a/core/java/android/widget/Magnifier.java
+++ b/core/java/android/widget/Magnifier.java
@@ -93,6 +93,8 @@ public final class Magnifier {
private final int mDefaultHorizontalSourceToMagnifierOffset;
// The vertical offset between the source and window coords when #show(float, float) is used.
private final int mDefaultVerticalSourceToMagnifierOffset;
+ // Whether the magnifier will be clamped inside the main surface and not overlap system insets.
+ private final boolean mForcePositionWithinWindowSystemInsetsBounds;
// The parent surface for the magnifier surface.
private SurfaceInfo mParentSurface;
// The surface where the content will be copied from.
@@ -141,6 +143,8 @@ public final class Magnifier {
params.mHorizontalDefaultSourceToMagnifierOffset;
mDefaultVerticalSourceToMagnifierOffset =
params.mVerticalDefaultSourceToMagnifierOffset;
+ mForcePositionWithinWindowSystemInsetsBounds =
+ params.mForcePositionWithinWindowSystemInsetsBounds;
// The view's surface coordinates will not be updated until the magnifier is first shown.
mViewCoordinatesInSurface = new int[2];
}
@@ -379,6 +383,17 @@ public final class Magnifier {
}
/**
+ * Returns whether the magnifier position will be adjusted such that the magnifier will be
+ * fully within the bounds of the main application window, by also avoiding any overlap with
+ * system insets (such as the one corresponding to the status bar).
+ * @return whether the magnifier position will be adjusted
+ * @see Magnifier.Builder#setForcePositionWithinWindowSystemInsetsBounds(boolean)
+ */
+ public boolean isForcePositionWithinWindowSystemInsetsBounds() {
+ return mForcePositionWithinWindowSystemInsetsBounds;
+ }
+
+ /**
* Returns the top left coordinates of the magnifier, relative to the surface of the
* main application window. They will be determined by the coordinates of the last
* {@link #show(float, float)} or {@link #show(float, float, float, float)} call, adjusted
@@ -567,6 +582,11 @@ public final class Magnifier {
* @return the current window coordinates, after they are clamped inside the parent surface
*/
private Point getCurrentClampedWindowCoordinates() {
+ if (!mForcePositionWithinWindowSystemInsetsBounds) {
+ // No position adjustment should be done, so return the raw coordinates.
+ return new Point(mWindowCoords);
+ }
+
final Rect windowBounds;
if (mParentSurface.mIsMainWindowSurface) {
final Insets systemInsets = mView.getRootWindowInsets().getSystemWindowInsets();
@@ -891,6 +911,7 @@ public final class Magnifier {
private @FloatRange(from = 0f) float mCornerRadius;
private int mHorizontalDefaultSourceToMagnifierOffset;
private int mVerticalDefaultSourceToMagnifierOffset;
+ private boolean mForcePositionWithinWindowSystemInsetsBounds;
/**
* Construct a new builder for {@link Magnifier} objects.
@@ -915,6 +936,7 @@ public final class Magnifier {
mVerticalDefaultSourceToMagnifierOffset =
a.getDimensionPixelSize(R.styleable.Magnifier_magnifierVerticalOffset, 0);
a.recycle();
+ mForcePositionWithinWindowSystemInsetsBounds = true;
}
/**
@@ -1000,6 +1022,28 @@ public final class Magnifier {
}
/**
+ * Defines the behavior of the magnifier when it is requested to position outside the
+ * surface of the main application window. The default value is {@code true}, which means
+ * that the position will be adjusted such that the magnifier will be fully within the
+ * bounds of the main application window, by also avoiding any overlap with system insets
+ * (such as the one corresponding to the status bar). If you require a custom behavior, this
+ * flag should be set to {@code false}, meaning that the magnifier will be able to cross the
+ * main application surface boundaries (and also overlap the system insets). This should be
+ * handled with care, when passing coordinates to {@link #show(float, float)}; note that:
+ * <ul>
+ * <li>in a multiwindow context, if the magnifier crosses the boundary between the two
+ * windows, it will not be able to show over the window of the other application</li>
+ * <li>if the magnifier overlaps the status bar, there is no guarantee about which one
+ * will be displayed on top. This should be handled with care.</li>
+ * </ul>
+ * @param force whether the magnifier position will be adjusted
+ */
+ public Builder setForcePositionWithinWindowSystemInsetsBounds(boolean force) {
+ mForcePositionWithinWindowSystemInsetsBounds = force;
+ return this;
+ }
+
+ /**
* Builds a {@link Magnifier} instance based on the configuration of this {@link Builder}.
*/
public @NonNull Magnifier build() {