OSDN Git Service

Refactoring Geometry handling.
[android-x86/packages-apps-Gallery2.git] / src / com / android / gallery3d / filtershow / imageshow / ImageStraighten.java
index 17df2b7..ff75dcc 100644 (file)
@@ -19,21 +19,52 @@ package com.android.gallery3d.filtershow.imageshow;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
 import android.graphics.Paint;
+import android.graphics.Paint.Style;
+import android.graphics.Path;
 import android.graphics.RectF;
 import android.util.AttributeSet;
+import android.view.MotionEvent;
 
-import com.android.gallery3d.R;
 import com.android.gallery3d.filtershow.editors.EditorStraighten;
+import com.android.gallery3d.filtershow.filters.FilterCropRepresentation;
+import com.android.gallery3d.filtershow.filters.FilterRepresentation;
+import com.android.gallery3d.filtershow.filters.FilterStraightenRepresentation;
+import com.android.gallery3d.filtershow.imageshow.GeometryMathUtils.GeometryHolder;
 
-public class ImageStraighten extends ImageGeometry {
+import java.util.ArrayList;
+import java.util.Collection;
 
+
+public class ImageStraighten extends ImageShow {
+    private static final String TAG = ImageStraighten.class.getSimpleName();
     private float mBaseAngle = 0;
     private float mAngle = 0;
+    private float mInitialAngle = 0;
+    private boolean mFirstDrawSinceUp = false;
     private EditorStraighten mEditorStraighten;
+    private FilterStraightenRepresentation mLocalRep = new FilterStraightenRepresentation();
+    private RectF mPriorCropAtUp = new RectF();
+    private RectF mDrawRect = new RectF();
+    private Path mDrawPath = new Path();
+    private GeometryHolder mDrawHolder = new GeometryHolder();
+    private enum MODES {
+        NONE, MOVE
+    }
+    private MODES mState = MODES.NONE;
+    private static final float MAX_STRAIGHTEN_ANGLE
+        = FilterStraightenRepresentation.MAX_STRAIGHTEN_ANGLE;
+    private static final float MIN_STRAIGHTEN_ANGLE
+        = FilterStraightenRepresentation.MIN_STRAIGHTEN_ANGLE;
+    private float mCurrentX;
+    private float mCurrentY;
+    private float mTouchCenterX;
+    private float mTouchCenterY;
+    private RectF mCrop = new RectF();
+    private final Paint mPaint = new Paint();
 
-    private static final String LOGTAG = "ImageStraighten";
-    private static final Paint gPaint = new Paint();
     public ImageStraighten(Context context) {
         super(context);
     }
@@ -42,23 +73,76 @@ public class ImageStraighten extends ImageGeometry {
         super(context, attrs);
     }
 
-    @Override
-    protected void setActionDown(float x, float y) {
-        super.setActionDown(x, y);
-        mBaseAngle = mAngle = getLocalStraighten();
+    public void setFilterStraightenRepresentation(FilterStraightenRepresentation rep) {
+        mLocalRep = (rep == null) ? new FilterStraightenRepresentation() : rep;
+        mInitialAngle = mBaseAngle = mAngle = mLocalRep.getStraighten();
     }
 
-    private void setCropToStraighten(){
-        setLocalCropBounds(getUntranslatedStraightenCropBounds(getLocalPhotoBounds(),
-                getLocalStraighten()));
+    public Collection<FilterRepresentation> getFinalRepresentation() {
+        ArrayList<FilterRepresentation> reps = new ArrayList<FilterRepresentation>(2);
+        reps.add(mLocalRep);
+        if (mInitialAngle != mLocalRep.getStraighten()) {
+            reps.add(new FilterCropRepresentation(mCrop));
+        }
+        return reps;
     }
 
     @Override
-    protected void setActionMove(float x, float y) {
-        super.setActionMove(x, y);
-        computeValue();
-        setLocalStraighten(mAngle);
-        setCropToStraighten();
+    public boolean onTouchEvent(MotionEvent event) {
+        float x = event.getX();
+        float y = event.getY();
+
+        switch (event.getActionMasked()) {
+            case (MotionEvent.ACTION_DOWN):
+                if (mState == MODES.NONE) {
+                    mTouchCenterX = x;
+                    mTouchCenterY = y;
+                    mCurrentX = x;
+                    mCurrentY = y;
+                    mState = MODES.MOVE;
+                    mBaseAngle = mAngle;
+                }
+                break;
+            case (MotionEvent.ACTION_UP):
+                if (mState == MODES.MOVE) {
+                    mState = MODES.NONE;
+                    mCurrentX = x;
+                    mCurrentY = y;
+                    computeValue();
+                    mFirstDrawSinceUp = true;
+                }
+                break;
+            case (MotionEvent.ACTION_MOVE):
+                if (mState == MODES.MOVE) {
+                    mCurrentX = x;
+                    mCurrentY = y;
+                    computeValue();
+                }
+                break;
+            default:
+                break;
+        }
+        invalidate();
+        return true;
+    }
+
+    private static float angleFor(float dx, float dy) {
+        return (float) (Math.atan2(dx, dy) * 180 / Math.PI);
+    }
+
+    private float getCurrentTouchAngle() {
+        float centerX = getWidth() / 2f;
+        float centerY = getHeight() / 2f;
+        if (mCurrentX == mTouchCenterX && mCurrentY == mTouchCenterY) {
+            return 0;
+        }
+        float dX1 = mTouchCenterX - centerX;
+        float dY1 = mTouchCenterY - centerY;
+        float dX2 = mCurrentX - centerX;
+        float dY2 = mCurrentY - centerY;
+        float angleA = angleFor(dX1, dY1);
+        float angleB = angleFor(dX2, dY2);
+        return (angleB - angleA) % 360;
     }
 
     private void computeValue() {
@@ -68,62 +152,105 @@ public class ImageStraighten extends ImageGeometry {
         mAngle = Math.min(MAX_STRAIGHTEN_ANGLE, mAngle);
     }
 
-    @Override
-    protected void lostVisibility() {
-        saveAndSetPreset();
+    private static void getUntranslatedStraightenCropBounds(RectF outRect, float straightenAngle) {
+        float deg = straightenAngle;
+        if (deg < 0) {
+            deg = -deg;
+        }
+        double a = Math.toRadians(deg);
+        double sina = Math.sin(a);
+        double cosa = Math.cos(a);
+        double rw = outRect.width();
+        double rh = outRect.height();
+        double h1 = rh * rh / (rw * sina + rh * cosa);
+        double h2 = rh * rw / (rw * cosa + rh * sina);
+        double hh = Math.min(h1, h2);
+        double ww = hh * rw / rh;
+        float left = (float) ((rw - ww) * 0.5f);
+        float top = (float) ((rh - hh) * 0.5f);
+        float right = (float) (left + ww);
+        float bottom = (float) (top + hh);
+        outRect.set(left, top, right, bottom);
     }
 
-    @Override
-    protected void gainedVisibility(){
-        setCropToStraighten();
+    private void updateCurrentCrop(Matrix m, GeometryHolder h, RectF tmp, int imageWidth,
+            int imageHeight, int viewWidth, int viewHeight) {
+        if (GeometryMathUtils.needsDimensionSwap(h.rotation)) {
+            tmp.set(0, 0, imageHeight, imageWidth);
+        } else {
+            tmp.set(0, 0, imageWidth, imageHeight);
+        }
+        float scale = GeometryMathUtils.scale(imageWidth, imageHeight, viewWidth, viewHeight);
+        GeometryMathUtils.scaleRect(tmp, scale);
+        getUntranslatedStraightenCropBounds(tmp, mAngle);
+        tmp.offset(viewWidth / 2f - tmp.centerX(), viewHeight / 2f - tmp.centerY());
+        h.straighten = 0;
+        Matrix m1 = GeometryMathUtils.getFullGeometryToScreenMatrix(h, imageWidth,
+                imageHeight, viewWidth, viewHeight);
+        m.reset();
+        m1.invert(m);
+        mCrop.set(tmp);
+        m.mapRect(mCrop);
+        FilterCropRepresentation.findNormalizedCrop(mCrop, imageWidth, imageHeight);
     }
 
-    @Override
-    protected void setActionUp() {
-        super.setActionUp();
-        setCropToStraighten();
-    }
 
     @Override
-    public void onNewValue(int value) {
-        setLocalStraighten(GeometryMath.clamp(value, MIN_STRAIGHTEN_ANGLE, MAX_STRAIGHTEN_ANGLE));
-        invalidate();
-    }
+    public void onDraw(Canvas canvas) {
+        MasterImage master = MasterImage.getImage();
+        Bitmap image = master.getFiltersOnlyImage();
+        if (image == null) {
+            return;
+        }
+        GeometryMathUtils.initializeHolder(mDrawHolder, mLocalRep);
+        mDrawHolder.straighten = mAngle;
+        int imageWidth = image.getWidth();
+        int imageHeight = image.getHeight();
+        int viewWidth = canvas.getWidth();
+        int viewHeight = canvas.getHeight();
 
-    @Override
-    protected int getLocalValue() {
-        return (int) getLocalStraighten();
-    }
+        // Get matrix for drawing bitmap
+        Matrix m = GeometryMathUtils.getFullGeometryToScreenMatrix(mDrawHolder, imageWidth,
+                imageHeight, viewWidth, viewHeight);
+        mPaint.reset();
+        mPaint.setAntiAlias(true);
+        mPaint.setFilterBitmap(true);
+        canvas.drawBitmap(image, m, mPaint);
 
-    @Override
-    protected void drawShape(Canvas canvas, Bitmap image) {
-        float [] o = {0, 0};
-        RectF bounds = drawTransformed(canvas, image, gPaint, o);
+        mPaint.setFilterBitmap(false);
+        mPaint.setColor(Color.WHITE);
+        mPaint.setStrokeWidth(2);
+        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
+        updateCurrentCrop(m, mDrawHolder, mDrawRect, imageWidth,
+                imageHeight, viewWidth, viewHeight);
+        if (mFirstDrawSinceUp) {
+            mPriorCropAtUp.set(mCrop);
+            mLocalRep.setStraighten(mAngle);
+            mFirstDrawSinceUp = false;
+        }
 
         // Draw the grid
-        gPaint.setARGB(255, 255, 255, 255);
-        gPaint.setStrokeWidth(3);
-        gPaint.setStyle(Paint.Style.FILL_AND_STROKE);
-
-        RectF display = getLocalDisplayBounds();
-        float dWidth = display.width();
-        float dHeight = display.height();
-
-        if (mMode == MODES.MOVE) {
+        if (mState == MODES.MOVE) {
             canvas.save();
-            canvas.clipRect(bounds);
-
+            canvas.clipRect(mDrawRect);
             int n = 16;
-            float step = dWidth / n;
+            float step = viewWidth / n;
             float p = 0;
             for (int i = 1; i < n; i++) {
                 p = i * step;
-                gPaint.setARGB(60, 255, 255, 255);
-                canvas.drawLine(p, 0, p, dHeight, gPaint);
-                canvas.drawLine(0, p, dWidth, p, gPaint);
+                mPaint.setAlpha(60);
+                canvas.drawLine(p, 0, p, viewHeight, mPaint);
+                canvas.drawLine(0, p, viewHeight, p, mPaint);
             }
             canvas.restore();
         }
+        mPaint.reset();
+        mPaint.setColor(Color.WHITE);
+        mPaint.setStyle(Style.STROKE);
+        mPaint.setStrokeWidth(3);
+        mDrawPath.reset();
+        mDrawPath.addRect(mDrawRect, Path.Direction.CW);
+        canvas.drawPath(mDrawPath, mPaint);
     }
 
     public void setEditor(EditorStraighten editorStraighten) {