Merge "Add MagnifierView to long screenshot UI." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
0e917e1f92
@@ -74,7 +74,7 @@
|
|||||||
android:id="@+id/preview"
|
android:id="@+id/preview"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="24dp"
|
android:layout_marginBottom="42dp"
|
||||||
android:layout_marginHorizontal="48dp"
|
android:layout_marginHorizontal="48dp"
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
app:layout_constrainedHeight="true"
|
app:layout_constrainedHeight="true"
|
||||||
@@ -91,19 +91,33 @@
|
|||||||
android:id="@+id/crop_view"
|
android:id="@+id/crop_view"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="24dp"
|
android:layout_marginBottom="42dp"
|
||||||
app:layout_constrainedHeight="true"
|
app:layout_constrainedHeight="true"
|
||||||
app:layout_constrainedWidth="true"
|
app:layout_constrainedWidth="true"
|
||||||
app:layout_constraintTop_toBottomOf="@id/guideline"
|
app:layout_constraintTop_toBottomOf="@id/guideline"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:handleThickness="3dp"
|
app:handleThickness="@dimen/screenshot_crop_handle_thickness"
|
||||||
app:handleColor="@*android:color/accent_device_default"
|
app:handleColor="@*android:color/accent_device_default"
|
||||||
app:scrimColor="#9444"
|
app:scrimColor="@color/screenshot_crop_scrim"
|
||||||
tools:background="?android:colorBackground"
|
tools:background="?android:colorBackground"
|
||||||
tools:minHeight="100dp"
|
tools:minHeight="100dp"
|
||||||
tools:minWidth="100dp" />
|
tools:minWidth="100dp" />
|
||||||
|
|
||||||
|
<com.android.systemui.screenshot.MagnifierView
|
||||||
|
android:id="@+id/magnifier"
|
||||||
|
android:visibility="invisible"
|
||||||
|
android:layout_width="200dp"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/guideline"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:handleThickness="@dimen/screenshot_crop_handle_thickness"
|
||||||
|
app:handleColor="@*android:color/accent_device_default"
|
||||||
|
app:scrimColor="@color/screenshot_crop_scrim"
|
||||||
|
app:borderThickness="4dp"
|
||||||
|
app:borderColor="#fff"
|
||||||
|
/>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -178,6 +178,14 @@
|
|||||||
<attr name="scrimColor" format="color" />
|
<attr name="scrimColor" format="color" />
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
|
<declare-styleable name="MagnifierView">
|
||||||
|
<attr name="handleThickness" format="dimension" />
|
||||||
|
<attr name="handleColor" format="color" />
|
||||||
|
<attr name="scrimColor" format="color" />
|
||||||
|
<attr name="borderThickness" format="dimension" />
|
||||||
|
<attr name="borderColor" format="color" />
|
||||||
|
</declare-styleable>
|
||||||
|
|
||||||
<declare-styleable name="RoundedCornerProgressDrawable">
|
<declare-styleable name="RoundedCornerProgressDrawable">
|
||||||
<attr name="android:drawable" />
|
<attr name="android:drawable" />
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|||||||
@@ -197,6 +197,9 @@
|
|||||||
<color name="global_screenshot_dismiss_foreground">@color/GM2_grey_500</color>
|
<color name="global_screenshot_dismiss_foreground">@color/GM2_grey_500</color>
|
||||||
<color name="global_screenshot_background_protection_start">#40000000</color> <!-- 25% black -->
|
<color name="global_screenshot_background_protection_start">#40000000</color> <!-- 25% black -->
|
||||||
|
|
||||||
|
<!-- Long screenshot UI -->
|
||||||
|
<color name="screenshot_crop_scrim">#9444</color>
|
||||||
|
|
||||||
<!-- GM2 colors -->
|
<!-- GM2 colors -->
|
||||||
<color name="GM2_grey_50">#F8F9FA</color>
|
<color name="GM2_grey_50">#F8F9FA</color>
|
||||||
<color name="GM2_grey_100">#F1F3F4</color>
|
<color name="GM2_grey_100">#F1F3F4</color>
|
||||||
|
|||||||
@@ -345,6 +345,7 @@
|
|||||||
<dimen name="screenshot_action_chip_padding_end">16dp</dimen>
|
<dimen name="screenshot_action_chip_padding_end">16dp</dimen>
|
||||||
<dimen name="screenshot_action_chip_text_size">14sp</dimen>
|
<dimen name="screenshot_action_chip_text_size">14sp</dimen>
|
||||||
<dimen name="screenshot_dismissal_height_delta">80dp</dimen>
|
<dimen name="screenshot_dismissal_height_delta">80dp</dimen>
|
||||||
|
<dimen name="screenshot_crop_handle_thickness">3dp</dimen>
|
||||||
|
|
||||||
|
|
||||||
<!-- The width of the view containing navigation buttons -->
|
<!-- The width of the view containing navigation buttons -->
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import com.android.systemui.R;
|
|||||||
* cropped out.
|
* cropped out.
|
||||||
*/
|
*/
|
||||||
public class CropView extends View {
|
public class CropView extends View {
|
||||||
private enum CropBoundary {
|
public enum CropBoundary {
|
||||||
NONE, TOP, BOTTOM
|
NONE, TOP, BOTTOM
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,8 +48,14 @@ public class CropView extends View {
|
|||||||
private float mTopCrop = 0f;
|
private float mTopCrop = 0f;
|
||||||
private float mBottomCrop = 1f;
|
private float mBottomCrop = 1f;
|
||||||
|
|
||||||
|
// When the user is dragging a handle, these variables store the distance between the top/bottom
|
||||||
|
// crop values and
|
||||||
|
private float mTopDelta = 0f;
|
||||||
|
private float mBottomDelta = 0f;
|
||||||
|
|
||||||
private CropBoundary mCurrentDraggingBoundary = CropBoundary.NONE;
|
private CropBoundary mCurrentDraggingBoundary = CropBoundary.NONE;
|
||||||
private float mLastY;
|
private float mStartingY; // y coordinate of ACTION_DOWN
|
||||||
|
private CropInteractionListener mCropInteractionListener;
|
||||||
|
|
||||||
public CropView(Context context, @Nullable AttributeSet attrs) {
|
public CropView(Context context, @Nullable AttributeSet attrs) {
|
||||||
this(context, attrs, 0);
|
this(context, attrs, 0);
|
||||||
@@ -73,54 +79,84 @@ public class CropView extends View {
|
|||||||
@Override
|
@Override
|
||||||
public void onDraw(Canvas canvas) {
|
public void onDraw(Canvas canvas) {
|
||||||
super.onDraw(canvas);
|
super.onDraw(canvas);
|
||||||
drawShade(canvas, 0, mTopCrop);
|
float top = mTopCrop + mTopDelta;
|
||||||
drawShade(canvas, mBottomCrop, 1f);
|
float bottom = mBottomCrop + mBottomDelta;
|
||||||
drawHandle(canvas, mTopCrop);
|
drawShade(canvas, 0, top);
|
||||||
drawHandle(canvas, mBottomCrop);
|
drawShade(canvas, bottom, 1f);
|
||||||
|
drawHandle(canvas, top);
|
||||||
|
drawHandle(canvas, bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
int topPx = fractionToPixels(mTopCrop);
|
int topPx = fractionToPixels(mTopCrop);
|
||||||
int bottomPx = fractionToPixels(mBottomCrop);
|
int bottomPx = fractionToPixels(mBottomCrop);
|
||||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
switch (event.getAction()) {
|
||||||
mCurrentDraggingBoundary = nearestBoundary(event, topPx, bottomPx);
|
case MotionEvent.ACTION_DOWN:
|
||||||
if (mCurrentDraggingBoundary != CropBoundary.NONE) {
|
mCurrentDraggingBoundary = nearestBoundary(event, topPx, bottomPx);
|
||||||
mLastY = event.getY();
|
if (mCurrentDraggingBoundary != CropBoundary.NONE) {
|
||||||
}
|
mStartingY = event.getY();
|
||||||
return true;
|
updateListener(event);
|
||||||
}
|
}
|
||||||
if (event.getAction() == MotionEvent.ACTION_MOVE
|
return true;
|
||||||
&& mCurrentDraggingBoundary != CropBoundary.NONE) {
|
case MotionEvent.ACTION_MOVE:
|
||||||
float delta = event.getY() - mLastY;
|
if (mCurrentDraggingBoundary != CropBoundary.NONE) {
|
||||||
if (mCurrentDraggingBoundary == CropBoundary.TOP) {
|
float delta = event.getY() - mStartingY;
|
||||||
mTopCrop = pixelsToFraction((int) MathUtils.constrain(topPx + delta, 0,
|
if (mCurrentDraggingBoundary == CropBoundary.TOP) {
|
||||||
bottomPx - 2 * mCropTouchMargin));
|
mTopDelta = pixelsToFraction((int) MathUtils.constrain(delta, -topPx,
|
||||||
} else { // Bottom
|
bottomPx - 2 * mCropTouchMargin - topPx));
|
||||||
mBottomCrop = pixelsToFraction((int) MathUtils.constrain(bottomPx + delta,
|
} else { // Bottom
|
||||||
topPx + 2 * mCropTouchMargin, getMeasuredHeight()));
|
mBottomDelta = pixelsToFraction((int) MathUtils.constrain(delta,
|
||||||
}
|
topPx + 2 * mCropTouchMargin - bottomPx,
|
||||||
mLastY = event.getY();
|
getMeasuredHeight() - bottomPx));
|
||||||
invalidate();
|
}
|
||||||
return true;
|
updateListener(event);
|
||||||
|
invalidate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
if (mCurrentDraggingBoundary != CropBoundary.NONE) {
|
||||||
|
// Commit the delta to the stored crop values.
|
||||||
|
mTopCrop += mTopDelta;
|
||||||
|
mBottomCrop += mBottomDelta;
|
||||||
|
mTopDelta = 0;
|
||||||
|
mBottomDelta = 0;
|
||||||
|
updateListener(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return super.onTouchEvent(event);
|
return super.onTouchEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return value [0,1] representing the position of the top crop boundary.
|
* @return value [0,1] representing the position of the top crop boundary. Does not reflect
|
||||||
|
* changes from any in-progress touch input.
|
||||||
*/
|
*/
|
||||||
public float getTopBoundary() {
|
public float getTopBoundary() {
|
||||||
return mTopCrop;
|
return mTopCrop;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return value [0,1] representing the position of the bottom crop boundary.
|
* @return value [0,1] representing the position of the bottom crop boundary. Does not reflect
|
||||||
|
* changes from any in-progress touch input.
|
||||||
*/
|
*/
|
||||||
public float getBottomBoundary() {
|
public float getBottomBoundary() {
|
||||||
return mBottomCrop;
|
return mBottomCrop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setCropInteractionListener(CropInteractionListener listener) {
|
||||||
|
mCropInteractionListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateListener(MotionEvent event) {
|
||||||
|
if (mCropInteractionListener != null) {
|
||||||
|
float boundaryPosition = (mCurrentDraggingBoundary == CropBoundary.TOP)
|
||||||
|
? mTopCrop + mTopDelta : mBottomCrop + mBottomDelta;
|
||||||
|
mCropInteractionListener.onCropMotionEvent(event, mCurrentDraggingBoundary,
|
||||||
|
boundaryPosition, fractionToPixels(boundaryPosition));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void drawShade(Canvas canvas, float fracStart, float fracEnd) {
|
private void drawShade(Canvas canvas, float fracStart, float fracEnd) {
|
||||||
canvas.drawRect(0, fractionToPixels(fracStart), getMeasuredWidth(),
|
canvas.drawRect(0, fractionToPixels(fracStart), getMeasuredWidth(),
|
||||||
fractionToPixels(fracEnd), mShadePaint);
|
fractionToPixels(fracEnd), mShadePaint);
|
||||||
@@ -148,4 +184,17 @@ public class CropView extends View {
|
|||||||
}
|
}
|
||||||
return CropBoundary.NONE;
|
return CropBoundary.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen for crop motion events and state.
|
||||||
|
*/
|
||||||
|
public interface CropInteractionListener {
|
||||||
|
/**
|
||||||
|
* Called whenever CropView has a MotionEvent that can impact the position of the crop
|
||||||
|
* boundaries.
|
||||||
|
*/
|
||||||
|
void onCropMotionEvent(MotionEvent event, CropBoundary boundary, float boundaryPosition,
|
||||||
|
int boundaryPositionPx);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.systemui.screenshot;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.android.systemui.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MagnifierView shows a full-res cropped circular display of a given ImageTileSet, contents and
|
||||||
|
* positioning dereived from events from a CropView to which it listens.
|
||||||
|
*
|
||||||
|
* Not meant to be a general-purpose magnifier!
|
||||||
|
*/
|
||||||
|
public class MagnifierView extends View implements CropView.CropInteractionListener {
|
||||||
|
private Drawable mDrawable;
|
||||||
|
|
||||||
|
private final Paint mShadePaint;
|
||||||
|
private final Paint mHandlePaint;
|
||||||
|
|
||||||
|
private Path mOuterCircle;
|
||||||
|
private Path mInnerCircle;
|
||||||
|
|
||||||
|
private Path mCheckerboard;
|
||||||
|
private Paint mCheckerboardPaint;
|
||||||
|
private final float mBorderPx;
|
||||||
|
private final int mBorderColor;
|
||||||
|
private float mCheckerboardBoxSize = 40;
|
||||||
|
|
||||||
|
private float mLastCropPosition;
|
||||||
|
private CropView.CropBoundary mCropBoundary;
|
||||||
|
|
||||||
|
public MagnifierView(Context context, @Nullable AttributeSet attrs) {
|
||||||
|
this(context, attrs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MagnifierView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
TypedArray t = context.getTheme().obtainStyledAttributes(
|
||||||
|
attrs, R.styleable.MagnifierView, 0, 0);
|
||||||
|
mShadePaint = new Paint();
|
||||||
|
mShadePaint.setColor(t.getColor(R.styleable.MagnifierView_scrimColor, Color.TRANSPARENT));
|
||||||
|
mHandlePaint = new Paint();
|
||||||
|
mHandlePaint.setColor(t.getColor(R.styleable.MagnifierView_handleColor, Color.BLACK));
|
||||||
|
mHandlePaint.setStrokeWidth(
|
||||||
|
t.getDimensionPixelSize(R.styleable.MagnifierView_handleThickness, 20));
|
||||||
|
mBorderPx = t.getDimensionPixelSize(R.styleable.MagnifierView_borderThickness, 0);
|
||||||
|
mBorderColor = t.getColor(R.styleable.MagnifierView_borderColor, Color.WHITE);
|
||||||
|
t.recycle();
|
||||||
|
mCheckerboardPaint = new Paint();
|
||||||
|
mCheckerboardPaint.setColor(Color.GRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImageTileset(ImageTileSet tiles) {
|
||||||
|
if (tiles != null) {
|
||||||
|
mDrawable = tiles.getDrawable();
|
||||||
|
mDrawable.setBounds(0, 0, tiles.getWidth(), tiles.getHeight());
|
||||||
|
} else {
|
||||||
|
mDrawable = null;
|
||||||
|
}
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||||
|
super.onLayout(changed, left, top, right, bottom);
|
||||||
|
int radius = getWidth() / 2;
|
||||||
|
mOuterCircle = new Path();
|
||||||
|
mOuterCircle.addCircle(radius, radius, radius, Path.Direction.CW);
|
||||||
|
mInnerCircle = new Path();
|
||||||
|
mInnerCircle.addCircle(radius, radius, radius - mBorderPx, Path.Direction.CW);
|
||||||
|
mCheckerboard = generateCheckerboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDraw(Canvas canvas) {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
|
||||||
|
// TODO: just draw a circle at the end instead of clipping like this?
|
||||||
|
canvas.clipPath(mOuterCircle);
|
||||||
|
canvas.drawColor(mBorderColor);
|
||||||
|
canvas.clipPath(mInnerCircle);
|
||||||
|
|
||||||
|
// Draw a checkerboard pattern for out of bounds.
|
||||||
|
canvas.drawPath(mCheckerboard, mCheckerboardPaint);
|
||||||
|
|
||||||
|
if (mDrawable != null) {
|
||||||
|
canvas.save();
|
||||||
|
// Translate such that the center of this view represents the center of the crop
|
||||||
|
// boundary.
|
||||||
|
canvas.translate(-mDrawable.getBounds().width() / 2 + getWidth() / 2,
|
||||||
|
-mDrawable.getBounds().height() * mLastCropPosition + getHeight() / 2);
|
||||||
|
mDrawable.draw(canvas);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect scrimRect = new Rect(0, 0, getWidth(), getHeight() / 2);
|
||||||
|
if (mCropBoundary == CropView.CropBoundary.BOTTOM) {
|
||||||
|
scrimRect.offset(0, getHeight() / 2);
|
||||||
|
}
|
||||||
|
canvas.drawRect(scrimRect, mShadePaint);
|
||||||
|
|
||||||
|
canvas.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2, mHandlePaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCropMotionEvent(MotionEvent event, CropView.CropBoundary boundary,
|
||||||
|
float cropPosition, int cropPositionPx) {
|
||||||
|
mCropBoundary = boundary;
|
||||||
|
switch (event.getAction()) {
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
mLastCropPosition = cropPosition;
|
||||||
|
setTranslationY(cropPositionPx - getHeight() / 2);
|
||||||
|
setPivotX(getWidth() / 2);
|
||||||
|
setPivotY(getHeight() / 2);
|
||||||
|
setScaleX(0.2f);
|
||||||
|
setScaleY(0.2f);
|
||||||
|
setAlpha(0f);
|
||||||
|
setTranslationX((getParentWidth() - getWidth()) / 2);
|
||||||
|
setVisibility(View.VISIBLE);
|
||||||
|
animate().alpha(1f).translationX(0).scaleX(1f).scaleY(1f).start();
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
mLastCropPosition = cropPosition;
|
||||||
|
setTranslationY(cropPositionPx - getHeight() / 2);
|
||||||
|
invalidate();
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
animate().alpha(0).translationX((getParentWidth() - getWidth()) / 2).scaleX(0.2f)
|
||||||
|
.scaleY(0.2f).withEndAction(() -> setVisibility(View.INVISIBLE)).start();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path generateCheckerboard() {
|
||||||
|
Path path = new Path();
|
||||||
|
int checkerWidth = (int) Math.ceil(getWidth() / mCheckerboardBoxSize);
|
||||||
|
int checkerHeight = (int) Math.ceil(getHeight() / mCheckerboardBoxSize);
|
||||||
|
|
||||||
|
for (int row = 0; row < checkerHeight; row++) {
|
||||||
|
// Alternate starting on the first and second column;
|
||||||
|
int colStart = (row % 2 == 0) ? 0 : 1;
|
||||||
|
for (int col = colStart; col < checkerWidth; col += 2) {
|
||||||
|
path.addRect(col * mCheckerboardBoxSize,
|
||||||
|
row * mCheckerboardBoxSize,
|
||||||
|
(col + 1) * mCheckerboardBoxSize,
|
||||||
|
(row + 1) * mCheckerboardBoxSize,
|
||||||
|
Path.Direction.CW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getParentWidth() {
|
||||||
|
return ((View) getParent()).getWidth();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -81,6 +81,7 @@ public class ScrollCaptureController implements OnComputeInternalInsetsListener
|
|||||||
private View mEdit;
|
private View mEdit;
|
||||||
private View mShare;
|
private View mShare;
|
||||||
private CropView mCropView;
|
private CropView mCropView;
|
||||||
|
private MagnifierView mMagnifierView;
|
||||||
|
|
||||||
public ScrollCaptureController(Context context, Connection connection, Executor uiExecutor,
|
public ScrollCaptureController(Context context, Connection connection, Executor uiExecutor,
|
||||||
Executor bgExecutor, ImageExporter exporter, UiEventLogger uiEventLogger) {
|
Executor bgExecutor, ImageExporter exporter, UiEventLogger uiEventLogger) {
|
||||||
@@ -120,13 +121,14 @@ public class ScrollCaptureController implements OnComputeInternalInsetsListener
|
|||||||
mEdit = findViewById(R.id.edit);
|
mEdit = findViewById(R.id.edit);
|
||||||
mShare = findViewById(R.id.share);
|
mShare = findViewById(R.id.share);
|
||||||
mCropView = findViewById(R.id.crop_view);
|
mCropView = findViewById(R.id.crop_view);
|
||||||
|
mMagnifierView = findViewById(R.id.magnifier);
|
||||||
|
mCropView.setCropInteractionListener(mMagnifierView);
|
||||||
|
|
||||||
mSave.setOnClickListener(this::onClicked);
|
mSave.setOnClickListener(this::onClicked);
|
||||||
mCancel.setOnClickListener(this::onClicked);
|
mCancel.setOnClickListener(this::onClicked);
|
||||||
mEdit.setOnClickListener(this::onClicked);
|
mEdit.setOnClickListener(this::onClicked);
|
||||||
mShare.setOnClickListener(this::onClicked);
|
mShare.setOnClickListener(this::onClicked);
|
||||||
|
|
||||||
//mPreview.setImageDrawable(mImageTileSet.getDrawable());
|
|
||||||
mConnection.start(this::startCapture);
|
mConnection.start(this::startCapture);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,6 +166,7 @@ public class ScrollCaptureController implements OnComputeInternalInsetsListener
|
|||||||
|
|
||||||
private void doFinish() {
|
private void doFinish() {
|
||||||
mPreview.setImageDrawable(null);
|
mPreview.setImageDrawable(null);
|
||||||
|
mMagnifierView.setImageTileset(null);
|
||||||
mImageTileSet.clear();
|
mImageTileSet.clear();
|
||||||
mCallback.onFinish();
|
mCallback.onFinish();
|
||||||
mWindow.getDecorView().getViewTreeObserver()
|
mWindow.getDecorView().getViewTreeObserver()
|
||||||
@@ -273,6 +276,7 @@ public class ScrollCaptureController implements OnComputeInternalInsetsListener
|
|||||||
session.end(mCallback::onFinish);
|
session.end(mCallback::onFinish);
|
||||||
} else {
|
} else {
|
||||||
mPreview.setImageDrawable(mImageTileSet.getDrawable());
|
mPreview.setImageDrawable(mImageTileSet.getDrawable());
|
||||||
|
mMagnifierView.setImageTileset(mImageTileSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user