Make CropView handle images that aren't full-height
Compute the ImageView's extra top and bottom padding when it gets a
drawable or does layout, pass that information to CropView to adjust
its boundaries accordingly.
Also give MagnifierView some elevation so it doesn't get obscured by the
buttons.
Bug: 180967209
Test: Take a long screenshot at the top of the settings app, observe
that the image isn't full height, ensure that crop handles properly
honor image bounds and those bounds are honored on export as well.
Change-Id: Iac859995b362724a0db00b666a6ff970a0ccba1d
This commit is contained in:
@@ -76,7 +76,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="42dp"
|
||||
android:layout_marginHorizontal="48dp"
|
||||
android:adjustViewBounds="true"
|
||||
app:layout_constrainedHeight="true"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintTop_toBottomOf="@id/guideline"
|
||||
@@ -110,6 +109,7 @@
|
||||
android:visibility="invisible"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="200dp"
|
||||
android:elevation="2dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/guideline"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:handleThickness="@dimen/screenshot_crop_handle_thickness"
|
||||
|
||||
@@ -65,6 +65,9 @@ public class CropView extends View {
|
||||
private float mTopDelta = 0f;
|
||||
private float mBottomDelta = 0f;
|
||||
|
||||
private int mExtraTopPadding;
|
||||
private int mExtraBottomPadding;
|
||||
|
||||
private CropBoundary mCurrentDraggingBoundary = CropBoundary.NONE;
|
||||
private float mStartingY; // y coordinate of ACTION_DOWN
|
||||
private CropInteractionListener mCropInteractionListener;
|
||||
@@ -117,12 +120,13 @@ public class CropView extends View {
|
||||
if (mCurrentDraggingBoundary != CropBoundary.NONE) {
|
||||
float delta = event.getY() - mStartingY;
|
||||
if (mCurrentDraggingBoundary == CropBoundary.TOP) {
|
||||
mTopDelta = pixelsToFraction((int) MathUtils.constrain(delta, -topPx,
|
||||
mTopDelta = pixelDistanceToFraction((int) MathUtils.constrain(delta,
|
||||
-topPx + mExtraTopPadding,
|
||||
bottomPx - 2 * mCropTouchMargin - topPx));
|
||||
} else { // Bottom
|
||||
mBottomDelta = pixelsToFraction((int) MathUtils.constrain(delta,
|
||||
mBottomDelta = pixelDistanceToFraction((int) MathUtils.constrain(delta,
|
||||
topPx + 2 * mCropTouchMargin - bottomPx,
|
||||
getHeight() - bottomPx));
|
||||
getHeight() - bottomPx - mExtraBottomPadding));
|
||||
}
|
||||
updateListener(event);
|
||||
invalidate();
|
||||
@@ -194,6 +198,16 @@ public class CropView extends View {
|
||||
animator.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set additional top and bottom padding for the image being cropped (used when the
|
||||
* corresponding ImageView doesn't take the full height).
|
||||
*/
|
||||
public void setExtraPadding(int top, int bottom) {
|
||||
mExtraTopPadding = top;
|
||||
mExtraBottomPadding = bottom;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return value [0,1] representing the position of the top crop boundary. Does not reflect
|
||||
* changes from any in-progress touch input.
|
||||
@@ -244,12 +258,22 @@ public class CropView extends View {
|
||||
true, mHandlePaint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given fraction position to pixel position within the View.
|
||||
*/
|
||||
private int fractionToPixels(float frac) {
|
||||
return (int) (frac * getHeight());
|
||||
return (int) (mExtraTopPadding + frac * getImageHeight());
|
||||
}
|
||||
|
||||
private float pixelsToFraction(int px) {
|
||||
return px / (float) getHeight();
|
||||
private int getImageHeight() {
|
||||
return getHeight() - mExtraTopPadding - mExtraBottomPadding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given pixel distance to fraction of the image.
|
||||
*/
|
||||
private float pixelDistanceToFraction(int px) {
|
||||
return px / (float) getImageHeight();
|
||||
}
|
||||
|
||||
private CropBoundary nearestBoundary(MotionEvent event, int topPx, int bottomPx) {
|
||||
|
||||
@@ -157,6 +157,9 @@ public class LongScreenshotActivity extends Activity {
|
||||
});
|
||||
}
|
||||
}
|
||||
mPreview.addOnLayoutChangeListener(
|
||||
(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
|
||||
updateCropLocation());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -305,6 +308,27 @@ public class LongScreenshotActivity extends Activity {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCropLocation() {
|
||||
Drawable drawable = mPreview.getDrawable();
|
||||
if (drawable == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
float imageRatio = drawable.getBounds().width() / (float) drawable.getBounds().height();
|
||||
float viewRatio = mPreview.getWidth() / (float) mPreview.getHeight();
|
||||
|
||||
if (imageRatio > viewRatio) {
|
||||
// Image is full width and height is constrained, compute extra padding to inform
|
||||
// CropView
|
||||
float imageHeight = mPreview.getHeight() * viewRatio / imageRatio;
|
||||
int extraPadding = (int) (mPreview.getHeight() - imageHeight) / 2;
|
||||
mCropView.setExtraPadding(extraPadding, extraPadding);
|
||||
} else {
|
||||
// Image is full height
|
||||
mCropView.setExtraPadding(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void doCapture() {
|
||||
mScrollCaptureController.start(mConnection,
|
||||
new ScrollCaptureController.ScrollCaptureCallback() {
|
||||
@@ -319,6 +343,7 @@ public class LongScreenshotActivity extends Activity {
|
||||
Log.i(TAG, "Got tiles " + imageTileSet.getWidth() + " x "
|
||||
+ imageTileSet.getHeight());
|
||||
mPreview.setImageDrawable(imageTileSet.getDrawable());
|
||||
updateCropLocation();
|
||||
mMagnifierView.setDrawable(imageTileSet.getDrawable(),
|
||||
imageTileSet.getWidth(), imageTileSet.getHeight());
|
||||
mCropView.animateBoundaryTo(CropView.CropBoundary.BOTTOM, 0.5f);
|
||||
|
||||
Reference in New Issue
Block a user