12c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard/*
22c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * Copyright (C) 2012 The Android Open Source Project
32c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard *
42c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * Licensed under the Apache License, Version 2.0 (the "License");
52c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * you may not use this file except in compliance with the License.
62c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * You may obtain a copy of the License at
72c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard *
82c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard *      http://www.apache.org/licenses/LICENSE-2.0
92c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard *
102c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * Unless required by applicable law or agreed to in writing, software
112c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * distributed under the License is distributed on an "AS IS" BASIS,
122c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * See the License for the specific language governing permissions and
142c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard * limitations under the License.
152c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard */
162c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard
172c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroardpackage com.android.gallery3d.filtershow.imageshow;
182c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard
192c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroardimport android.content.Context;
2091d26f6c3b183862eeffc1856e2d758e800d13f4John Hofordimport android.graphics.Bitmap;
2144a499a64158cd5a12f8e44655f82b68c33bf3b2John Hofordimport android.graphics.Canvas;
2291d26f6c3b183862eeffc1856e2d758e800d13f4John Hofordimport android.graphics.RectF;
232c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroardimport android.util.AttributeSet;
242c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroardimport android.view.MotionEvent;
2591d26f6c3b183862eeffc1856e2d758e800d13f4John Hofordimport android.view.ScaleGestureDetector;
2691d26f6c3b183862eeffc1856e2d758e800d13f4John Hofordimport android.view.ScaleGestureDetector.OnScaleGestureListener;
272c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard
28a93d5ee9c409e2328dcbe2326591436f8ac23146John Hofordimport com.android.gallery3d.filtershow.editors.BasicEditor;
2991d26f6c3b183862eeffc1856e2d758e800d13f4John Hofordimport com.android.gallery3d.filtershow.editors.EditorTinyPlanet;
3044a499a64158cd5a12f8e44655f82b68c33bf3b2John Hofordimport com.android.gallery3d.filtershow.filters.FilterTinyPlanetRepresentation;
312c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard
3263a7dac01d394523799939596b960cb03321798dJohn Hofordpublic class ImageTinyPlanet extends ImageShow {
3391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford    private static final String LOGTAG = "ImageTinyPlanet";
342c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard
352c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard    private float mTouchCenterX = 0;
362c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard    private float mTouchCenterY = 0;
372c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard    private float mCurrentX = 0;
382c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard    private float mCurrentY = 0;
392c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard    private float mCenterX = 0;
402c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard    private float mCenterY = 0;
412c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard    private float mStartAngle = 0;
4244a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford    private FilterTinyPlanetRepresentation mTinyPlanetRep;
4391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford    private EditorTinyPlanet mEditorTinyPlanet;
4491d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford    private ScaleGestureDetector mScaleGestureDetector = null;
4591d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford    boolean mInScale = false;
4691d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford    RectF mDestRect = new RectF();
4791d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford
4891d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford    OnScaleGestureListener mScaleGestureListener = new OnScaleGestureListener() {
4991d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        private float mScale = 100;
5091d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        @Override
5191d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        public void onScaleEnd(ScaleGestureDetector detector) {
5291d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            mInScale = false;
5391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        }
5491d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford
5591d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        @Override
5691d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        public boolean onScaleBegin(ScaleGestureDetector detector) {
5791d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            mInScale = true;
5891d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            mScale = mTinyPlanetRep.getValue();
5991d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            return true;
6091d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        }
6191d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford
6291d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        @Override
6391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        public boolean onScale(ScaleGestureDetector detector) {
6491d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            int value = mTinyPlanetRep.getValue();
6591d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            mScale *= detector.getScaleFactor();
6691d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            value = (int) (mScale);
6791d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            value = Math.min(mTinyPlanetRep.getMaximum(), value);
6891d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            value = Math.max(mTinyPlanetRep.getMinimum(), value);
6991d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            mTinyPlanetRep.setValue(value);
7091d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            invalidate();
7191d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            mEditorTinyPlanet.commitLocalRepresentation();
7291d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            mEditorTinyPlanet.updateUI();
7391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            return true;
7491d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        }
7591d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford    };
762c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard
772c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard    public ImageTinyPlanet(Context context) {
782c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        super(context);
7991d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        mScaleGestureDetector = new ScaleGestureDetector(context, mScaleGestureListener);
802c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard    }
812c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard
822c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard    public ImageTinyPlanet(Context context, AttributeSet attrs) {
832c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        super(context, attrs);
8491d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        mScaleGestureDetector = new ScaleGestureDetector(context,mScaleGestureListener );
852c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard    }
862c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard
872c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard    protected static float angleFor(float dx, float dy) {
882c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        return (float) (Math.atan2(dx, dy) * 180 / Math.PI);
892c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard    }
902c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard
912c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard    protected float getCurrentTouchAngle() {
922c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        if (mCurrentX == mTouchCenterX && mCurrentY == mTouchCenterY) {
932c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard            return 0;
942c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        }
952c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        float dX1 = mTouchCenterX - mCenterX;
962c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        float dY1 = mTouchCenterY - mCenterY;
972c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        float dX2 = mCurrentX - mCenterX;
982c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        float dY2 = mCurrentY - mCenterY;
992c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard
1002c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        float angleA = angleFor(dX1, dY1);
1012c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        float angleB = angleFor(dX2, dY2);
1022c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        return (float) (((angleB - angleA) % 360) * Math.PI / 180);
1032c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard    }
1042c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard
1052c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard    @Override
1062c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard    public boolean onTouchEvent(MotionEvent event) {
1072c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        float x = event.getX();
1082c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        float y = event.getY();
1092c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        mCurrentX = x;
1102c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        mCurrentY = y;
1112c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        mCenterX = getWidth() / 2;
1122c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        mCenterY = getHeight() / 2;
11391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        mScaleGestureDetector.onTouchEvent(event);
11491d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        if (mInScale) {
11591d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            return true;
11691d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        }
1172c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        switch (event.getActionMasked()) {
1182c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard            case (MotionEvent.ACTION_DOWN):
1192c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard                mTouchCenterX = x;
1202c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard                mTouchCenterY = y;
12144a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford                mStartAngle = mTinyPlanetRep.getAngle();
1222c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard                break;
12391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford
1242c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard            case (MotionEvent.ACTION_MOVE):
12544a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford                mTinyPlanetRep.setAngle(mStartAngle + getCurrentTouchAngle());
1262c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard                break;
1272c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        }
1282c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        invalidate();
12944a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford        mEditorTinyPlanet.commitLocalRepresentation();
1302c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard        return true;
1312c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard    }
13244a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford
13344a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford    public void setRepresentation(FilterTinyPlanetRepresentation tinyPlanetRep) {
13444a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford        mTinyPlanetRep = tinyPlanetRep;
13544a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford    }
13644a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford
137a93d5ee9c409e2328dcbe2326591436f8ac23146John Hoford    public void setEditor(BasicEditor editorTinyPlanet) {
13891d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        mEditorTinyPlanet = (EditorTinyPlanet) editorTinyPlanet;
13944a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford    }
14044a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford
14144a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford    @Override
14244a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford    public void onDraw(Canvas canvas) {
14391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        Bitmap bitmap = MasterImage.getImage().getHighresImage();
14491d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        if (bitmap == null) {
14591d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            bitmap = MasterImage.getImage().getFilteredImage();
14691d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        }
14791d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford
14891d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        if (bitmap != null) {
14991d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            display(canvas, bitmap);
15091d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        }
15144a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford    }
15244a499a64158cd5a12f8e44655f82b68c33bf3b2John Hoford
15391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford    private void display(Canvas canvas, Bitmap bitmap) {
15491d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        float sw = canvas.getWidth();
15591d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        float sh = canvas.getHeight();
15691d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        float iw = bitmap.getWidth();
15791d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        float ih = bitmap.getHeight();
15891d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        float nsw = sw;
15991d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        float nsh = sh;
16091d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford
16191d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        if (sw * ih > sh * iw) {
16291d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            nsw = sh * iw / ih;
16391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        } else {
16491d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford            nsh = sw * ih / iw;
16591d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        }
16691d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford
16791d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        mDestRect.left = (sw - nsw) / 2;
16891d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        mDestRect.top = (sh - nsh) / 2;
16991d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        mDestRect.right = sw - mDestRect.left;
17091d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        mDestRect.bottom = sh - mDestRect.top;
17191d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford
17291d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford        canvas.drawBitmap(bitmap, null, mDestRect, mPaint);
17391d26f6c3b183862eeffc1856e2d758e800d13f4John Hoford    }
1742c6ea941a80ea22317d664e329aed51f5f7417b9nicolasroard}
175