Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 37d6b6d5 authored by Matt Casey's avatar Matt Casey
Browse files

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
parent e4aa751d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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"
+30 −6
Original line number Diff line number Diff line
@@ -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 int getImageHeight() {
        return getHeight() - mExtraTopPadding - mExtraBottomPadding;
    }

    private float pixelsToFraction(int px) {
        return px / (float) getHeight();
    /**
     * 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) {
+25 −0
Original line number Diff line number Diff line
@@ -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);