1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.gallery3d.filtershow.imageshow;
18 
19 import android.content.Context;
20 import android.graphics.Bitmap;
21 import android.graphics.Canvas;
22 import android.graphics.RectF;
23 import android.util.AttributeSet;
24 import android.view.MotionEvent;
25 import android.view.ScaleGestureDetector;
26 import android.view.ScaleGestureDetector.OnScaleGestureListener;
27 
28 import com.android.gallery3d.filtershow.editors.BasicEditor;
29 import com.android.gallery3d.filtershow.editors.EditorTinyPlanet;
30 import com.android.gallery3d.filtershow.filters.FilterTinyPlanetRepresentation;
31 
32 public class ImageTinyPlanet extends ImageShow {
33     private static final String LOGTAG = "ImageTinyPlanet";
34 
35     private float mTouchCenterX = 0;
36     private float mTouchCenterY = 0;
37     private float mCurrentX = 0;
38     private float mCurrentY = 0;
39     private float mCenterX = 0;
40     private float mCenterY = 0;
41     private float mStartAngle = 0;
42     private FilterTinyPlanetRepresentation mTinyPlanetRep;
43     private EditorTinyPlanet mEditorTinyPlanet;
44     private ScaleGestureDetector mScaleGestureDetector = null;
45     boolean mInScale = false;
46     RectF mDestRect = new RectF();
47 
48     OnScaleGestureListener mScaleGestureListener = new OnScaleGestureListener() {
49         private float mScale = 100;
50         @Override
51         public void onScaleEnd(ScaleGestureDetector detector) {
52             mInScale = false;
53         }
54 
55         @Override
56         public boolean onScaleBegin(ScaleGestureDetector detector) {
57             mInScale = true;
58             mScale = mTinyPlanetRep.getValue();
59             return true;
60         }
61 
62         @Override
63         public boolean onScale(ScaleGestureDetector detector) {
64             int value = mTinyPlanetRep.getValue();
65             mScale *= detector.getScaleFactor();
66             value = (int) (mScale);
67             value = Math.min(mTinyPlanetRep.getMaximum(), value);
68             value = Math.max(mTinyPlanetRep.getMinimum(), value);
69             mTinyPlanetRep.setValue(value);
70             invalidate();
71             mEditorTinyPlanet.commitLocalRepresentation();
72             mEditorTinyPlanet.updateUI();
73             return true;
74         }
75     };
76 
ImageTinyPlanet(Context context)77     public ImageTinyPlanet(Context context) {
78         super(context);
79         mScaleGestureDetector = new ScaleGestureDetector(context, mScaleGestureListener);
80     }
81 
ImageTinyPlanet(Context context, AttributeSet attrs)82     public ImageTinyPlanet(Context context, AttributeSet attrs) {
83         super(context, attrs);
84         mScaleGestureDetector = new ScaleGestureDetector(context,mScaleGestureListener );
85     }
86 
angleFor(float dx, float dy)87     protected static float angleFor(float dx, float dy) {
88         return (float) (Math.atan2(dx, dy) * 180 / Math.PI);
89     }
90 
getCurrentTouchAngle()91     protected float getCurrentTouchAngle() {
92         if (mCurrentX == mTouchCenterX && mCurrentY == mTouchCenterY) {
93             return 0;
94         }
95         float dX1 = mTouchCenterX - mCenterX;
96         float dY1 = mTouchCenterY - mCenterY;
97         float dX2 = mCurrentX - mCenterX;
98         float dY2 = mCurrentY - mCenterY;
99 
100         float angleA = angleFor(dX1, dY1);
101         float angleB = angleFor(dX2, dY2);
102         return (float) (((angleB - angleA) % 360) * Math.PI / 180);
103     }
104 
105     @Override
onTouchEvent(MotionEvent event)106     public boolean onTouchEvent(MotionEvent event) {
107         float x = event.getX();
108         float y = event.getY();
109         mCurrentX = x;
110         mCurrentY = y;
111         mCenterX = getWidth() / 2;
112         mCenterY = getHeight() / 2;
113         mScaleGestureDetector.onTouchEvent(event);
114         if (mInScale) {
115             return true;
116         }
117         switch (event.getActionMasked()) {
118             case (MotionEvent.ACTION_DOWN):
119                 mTouchCenterX = x;
120                 mTouchCenterY = y;
121                 mStartAngle = mTinyPlanetRep.getAngle();
122                 break;
123 
124             case (MotionEvent.ACTION_MOVE):
125                 mTinyPlanetRep.setAngle(mStartAngle + getCurrentTouchAngle());
126                 break;
127         }
128         invalidate();
129         mEditorTinyPlanet.commitLocalRepresentation();
130         return true;
131     }
132 
setRepresentation(FilterTinyPlanetRepresentation tinyPlanetRep)133     public void setRepresentation(FilterTinyPlanetRepresentation tinyPlanetRep) {
134         mTinyPlanetRep = tinyPlanetRep;
135     }
136 
setEditor(BasicEditor editorTinyPlanet)137     public void setEditor(BasicEditor editorTinyPlanet) {
138         mEditorTinyPlanet = (EditorTinyPlanet) editorTinyPlanet;
139     }
140 
141     @Override
onDraw(Canvas canvas)142     public void onDraw(Canvas canvas) {
143         Bitmap bitmap = PrimaryImage.getImage().getHighresImage();
144         if (bitmap == null) {
145             bitmap = PrimaryImage.getImage().getFilteredImage();
146         }
147 
148         if (bitmap != null) {
149             display(canvas, bitmap);
150         }
151     }
152 
display(Canvas canvas, Bitmap bitmap)153     private void display(Canvas canvas, Bitmap bitmap) {
154         float sw = canvas.getWidth();
155         float sh = canvas.getHeight();
156         float iw = bitmap.getWidth();
157         float ih = bitmap.getHeight();
158         float nsw = sw;
159         float nsh = sh;
160 
161         if (sw * ih > sh * iw) {
162             nsw = sh * iw / ih;
163         } else {
164             nsh = sw * ih / iw;
165         }
166 
167         mDestRect.left = (sw - nsw) / 2;
168         mDestRect.top = (sh - nsh) / 2;
169         mDestRect.right = sw - mDestRect.left;
170         mDestRect.bottom = sh - mDestRect.top;
171 
172         canvas.drawBitmap(bitmap, null, mDestRect, mPaint);
173     }
174 }
175