From c166f5c4c34478f1c192fbbfc4c7e1f993bd2ad1 Mon Sep 17 00:00:00 2001 From: Ruben Brunk Date: Thu, 25 Apr 2013 16:31:57 -0700 Subject: [PATCH] Cleanup crop activity UI. Bug: 8734193 Bug: 8723843 Change-Id: I09f0e8fcb0d919c573ad9a6f7b9f060f667d1d0d --- res/values/crop_colors.xml | 2 +- res/values/crop_dimens.xml | 2 + .../gallery3d/filtershow/crop/CropActivity.java | 46 ++++++++++++++++---- .../filtershow/crop/CropDrawingUtils.java | 4 ++ .../gallery3d/filtershow/crop/CropMath.java | 11 +++++ .../gallery3d/filtershow/crop/CropView.java | 50 ++++++++++++++++++++-- 6 files changed, 102 insertions(+), 13 deletions(-) diff --git a/res/values/crop_colors.xml b/res/values/crop_colors.xml index 712c7fc7e..3f64c5050 100644 --- a/res/values/crop_colors.xml +++ b/res/values/crop_colors.xml @@ -15,6 +15,6 @@ --> #CF000000 - #5F000000 + #4F000000 #7FFFFFFF diff --git a/res/values/crop_dimens.xml b/res/values/crop_dimens.xml index a79c2c906..fc91dbfb2 100644 --- a/res/values/crop_dimens.xml +++ b/res/values/crop_dimens.xml @@ -18,4 +18,6 @@ 5dp 45dp 20dp + 4dp + 4dp diff --git a/src/com/android/gallery3d/filtershow/crop/CropActivity.java b/src/com/android/gallery3d/filtershow/crop/CropActivity.java index 17b7a4e6d..0558e4a7e 100644 --- a/src/com/android/gallery3d/filtershow/crop/CropActivity.java +++ b/src/com/android/gallery3d/filtershow/crop/CropActivity.java @@ -26,7 +26,9 @@ import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; import android.graphics.BitmapRegionDecoder; +import android.graphics.Canvas; import android.graphics.Matrix; +import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.net.Uri; @@ -58,6 +60,8 @@ public class CropActivity extends Activity { private CropExtras mCropExtras = null; private LoadBitmapTask mLoadBitmapTask = null; + private int mOutputX = 0; + private int mOutputY = 0; private Bitmap mOriginalBitmap = null; private RectF mOriginalBounds = null; private int mOriginalRotation = 0; @@ -194,16 +198,20 @@ public class CropActivity extends Activity { if (mCropExtras != null) { int aspectX = mCropExtras.getAspectX(); int aspectY = mCropExtras.getAspectY(); - int outputX = mCropExtras.getOutputX(); - int outputY = mCropExtras.getOutputY(); - if (outputX > 0 && outputY > 0) { - mCropView.applyAspect(outputX, outputY); + mOutputX = mCropExtras.getOutputX(); + mOutputY = mCropExtras.getOutputY(); + if (mOutputX > 0 && mOutputY > 0) { + mCropView.applyAspect(mOutputX, mOutputY); + + } + float spotX = mCropExtras.getSpotlightX(); + float spotY = mCropExtras.getSpotlightY(); + if (spotX > 0 && spotY > 0) { + mCropView.setWallpaperSpotlight(spotX, spotY); } if (aspectX > 0 && aspectY > 0) { mCropView.applyAspect(aspectX, aspectY); } - mCropView.setWallpaperSpotlight(mCropExtras.getSpotlightX(), - mCropExtras.getSpotlightY()); } enableSave(true); } else { @@ -318,7 +326,7 @@ public class CropActivity extends Activity { final View loading = findViewById(R.id.loading); loading.setVisibility(View.VISIBLE); BitmapIOTask ioTask = new BitmapIOTask(sourceUri, destUri, format, flags, cropBounds, - photoBounds, currentBitmapBounds, rotation); + photoBounds, currentBitmapBounds, rotation, mOutputX, mOutputY); ioTask.execute(currentBitmap); } @@ -349,7 +357,8 @@ public class CropActivity extends Activity { int mRotation = 0; public BitmapIOTask(Uri sourceUri, Uri destUri, String outputFormat, int flags, - RectF cropBounds, RectF photoBounds, RectF originalBitmapBounds, int rotation) { + RectF cropBounds, RectF photoBounds, RectF originalBitmapBounds, int rotation, + int outputX, int outputY) { mOutputFormat = outputFormat; mOutStream = null; mOutUri = destUri; @@ -363,6 +372,8 @@ public class CropActivity extends Activity { mRotation = (rotation < 0) ? -rotation : rotation; mRotation %= 360; mRotation = 90 * (int) (mRotation / 90); // now mRotation is a multiple of 90 + mOutputX = outputX; + mOutputY = outputY; if ((flags & DO_EXTRA_OUTPUT) != 0) { if (mOutUri == null) { @@ -470,7 +481,24 @@ public class CropActivity extends Activity { failure = true; return false; } - if (mRotation > 0) { + if (mOutputX > 0 && mOutputY > 0) { + Matrix m = new Matrix(); + RectF cropRect = new RectF(0, 0, crop.getWidth(), crop.getHeight()); + if (mRotation > 0) { + m.setRotate(mRotation); + m.mapRect(cropRect); + } + RectF returnRect = new RectF(0, 0, mOutputX, mOutputY); + m.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL); + m.preRotate(mRotation); + Bitmap tmp = Bitmap.createBitmap((int) returnRect.width(), + (int) returnRect.height(), Bitmap.Config.ARGB_8888); + if (tmp != null) { + Canvas c = new Canvas(tmp); + c.drawBitmap(crop, m, new Paint()); + crop = tmp; + } + } else if (mRotation > 0) { Matrix m = new Matrix(); m.setRotate(mRotation); Bitmap tmp = Bitmap.createBitmap(crop, 0, 0, crop.getWidth(), diff --git a/src/com/android/gallery3d/filtershow/crop/CropDrawingUtils.java b/src/com/android/gallery3d/filtershow/crop/CropDrawingUtils.java index 7c54cff76..b0d324cbb 100644 --- a/src/com/android/gallery3d/filtershow/crop/CropDrawingUtils.java +++ b/src/com/android/gallery3d/filtershow/crop/CropDrawingUtils.java @@ -113,7 +113,11 @@ public abstract class CropDrawingUtils { canvas.restore(); Path path = new Path(); path.moveTo(r1.left, r1.top); + path.lineTo(r1.right, r1.top); + path.moveTo(r1.left, r1.top); path.lineTo(r1.left, r1.bottom); + path.moveTo(r1.left, r1.bottom); + path.lineTo(r1.right, r1.bottom); path.moveTo(r1.right, r1.top); path.lineTo(r1.right, r1.bottom); path.moveTo(r2.left, r2.top); diff --git a/src/com/android/gallery3d/filtershow/crop/CropMath.java b/src/com/android/gallery3d/filtershow/crop/CropMath.java index ed800c912..849ac60ef 100644 --- a/src/com/android/gallery3d/filtershow/crop/CropMath.java +++ b/src/com/android/gallery3d/filtershow/crop/CropMath.java @@ -235,6 +235,17 @@ public class CropMath { return bmap.getRowBytes() * bmap.getHeight(); } + /** + * Constrains rotation to be in [0, 90, 180, 270] rounding down. + * @param rotation any rotation value, in degrees + * @return integer rotation in [0, 90, 180, 270] + */ + public static int constrainedRotation(float rotation) { + int r = (int) ((rotation % 360) / 90); + r = (r < 0) ? (r + 4) : r; + return r * 90; + } + private static float getUnrotated(float[] rotatedRect, float[] center, RectF unrotated) { float dy = rotatedRect[1] - rotatedRect[3]; float dx = rotatedRect[0] - rotatedRect[2]; diff --git a/src/com/android/gallery3d/filtershow/crop/CropView.java b/src/com/android/gallery3d/filtershow/crop/CropView.java index 08c38836e..87e454270 100644 --- a/src/com/android/gallery3d/filtershow/crop/CropView.java +++ b/src/com/android/gallery3d/filtershow/crop/CropView.java @@ -71,6 +71,8 @@ public class CropView extends View { private int mWPMarkerColor = 0x7FFFFFFF; private int mMinSideSize = 90; private int mTouchTolerance = 40; + private float mDashOnLength = 20; + private float mDashOffLength = 10; private enum Mode { NONE, MOVE @@ -91,6 +93,8 @@ public class CropView extends View { mOverlayShadowColor = (int) rsc.getColor(R.color.crop_shadow_color); mOverlayWPShadowColor = (int) rsc.getColor(R.color.crop_shadow_wp_color); mWPMarkerColor = (int) rsc.getColor(R.color.crop_wp_markers); + mDashOnLength = rsc.getDimension(R.dimen.wp_selector_dash_length); + mDashOffLength = rsc.getDimension(R.dimen.wp_selector_off_length); } public void initialize(Bitmap image, RectF newCropBounds, RectF newPhotoBounds, int rotation) { @@ -212,6 +216,12 @@ public class CropView extends View { if (x <= 0 || y <= 0) { throw new IllegalArgumentException("Bad arguments to applyAspect"); } + // If we are rotated by 90 degrees from horizontal, swap x and y + if (((mRotation < 0) ? -mRotation : mRotation) % 180 == 90) { + float tmp = x; + x = y; + y = tmp; + } if (!mCropObj.setInnerAspectRatio(x, y)) { Log.w(LOGTAG, "failed to set aspect ratio"); } @@ -230,6 +240,38 @@ public class CropView extends View { mDoSpot = false; } + /** + * Rotates first d bits in integer x to the left some number of times. + */ + private int bitCycleLeft(int x, int times, int d) { + int mask = (1 << d) - 1; + int mout = x & mask; + times %= d; + int hi = mout >> (d - times); + int low = (mout << times) & mask; + int ret = x & ~mask; + ret |= low; + ret |= hi; + return ret; + } + + /** + * Find the selected edge or corner in screen coordinates. + */ + private int decode(int movingEdges, float rotation) { + int rot = CropMath.constrainedRotation(rotation); + switch (rot) { + case 90: + return bitCycleLeft(movingEdges, 1, 4); + case 180: + return bitCycleLeft(movingEdges, 2, 4); + case 270: + return bitCycleLeft(movingEdges, 3, 4); + default: + return movingEdges; + } + } + @Override public void onDraw(Canvas canvas) { if (mBitmap == null) { @@ -307,12 +349,14 @@ public class CropView extends View { wpPaint.setColor(mWPMarkerColor); wpPaint.setStrokeWidth(3); wpPaint.setStyle(Paint.Style.STROKE); - wpPaint.setPathEffect(new DashPathEffect(new float[] {20, 30}, 0)); + wpPaint.setPathEffect(new DashPathEffect(new float[] + {mDashOnLength, mDashOnLength + mDashOffLength}, 0)); p.setColor(mOverlayWPShadowColor); - CropDrawingUtils.drawWallpaperSelectionFrame(canvas, mScreenCropBounds, mSpotX, mSpotY, wpPaint, p); + CropDrawingUtils.drawWallpaperSelectionFrame(canvas, mScreenCropBounds, + mSpotX, mSpotY, wpPaint, p); } CropDrawingUtils.drawIndicators(canvas, mCropIndicator, mIndicatorSize, - mScreenCropBounds, mCropObj.isFixedAspect(), mCropObj.getSelectState()); + mScreenCropBounds, mCropObj.isFixedAspect(), decode(mCropObj.getSelectState(), mRotation)); } } -- 2.11.0