1 /*
2  * Copyright (C) 2013 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.Canvas;
21 import android.graphics.Matrix;
22 import android.util.AttributeSet;
23 import android.view.MotionEvent;
24 
25 import com.android.gallery3d.filtershow.editors.EditorVignette;
26 import com.android.gallery3d.filtershow.filters.FilterVignetteRepresentation;
27 
28 public class ImageVignette extends ImageShow {
29     private static final String LOGTAG = "ImageVignette";
30 
31     private FilterVignetteRepresentation mVignetteRep;
32     private EditorVignette mEditorVignette;
33     private OvalSpaceAdapter mScreenOval = new OvalSpaceAdapter();
34     private int mActiveHandle = -1;
35 
36     EclipseControl mElipse;
37 
ImageVignette(Context context)38     public ImageVignette(Context context) {
39         super(context);
40         mElipse = new EclipseControl(context);
41     }
42 
ImageVignette(Context context, AttributeSet attrs)43     public ImageVignette(Context context, AttributeSet attrs) {
44         super(context, attrs);
45         mElipse = new EclipseControl(context);
46     }
47 
48     static class OvalSpaceAdapter implements Oval {
49         private Oval mOval;
50         Matrix mToScr;
51         Matrix mToImage;
52         int mImgWidth;
53         int mImgHeight;
54         float[] mTmp = new float[2];
55         float mTmpRadiusX;
56         float mTmpRadiusY;
57 
setImageOval(Oval oval)58         public void setImageOval(Oval oval) {
59             mOval = oval;
60         }
61 
setTransform(Matrix toScr, Matrix toImage, int imgWidth, int imgHeight)62         public void setTransform(Matrix toScr, Matrix toImage, int imgWidth, int imgHeight) {
63             mToScr = toScr;
64             mToImage = toImage;
65             mImgWidth = imgWidth;
66             mImgHeight = imgHeight;
67             mTmpRadiusX = getRadiusX();
68             mTmpRadiusY = getRadiusY();
69         }
70 
71         @Override
setCenter(float x, float y)72         public void setCenter(float x, float y) {
73             mTmp[0] = x;
74             mTmp[1] = y;
75             mToImage.mapPoints(mTmp);
76             mOval.setCenter(mTmp[0] / mImgWidth, mTmp[1] / mImgHeight);
77         }
78 
79         @Override
setRadius(float w, float h)80         public void setRadius(float w, float h) {
81             mTmp[0] = mTmpRadiusX = w;
82             mTmp[1] = mTmpRadiusY = h;
83             mToImage.mapVectors(mTmp);
84             mOval.setRadius(mTmp[0] / mImgWidth, mTmp[1] / mImgHeight);
85         }
86 
87         @Override
getCenterX()88         public float getCenterX() {
89             mTmp[0] = mOval.getCenterX() * mImgWidth;
90             mTmp[1] = mOval.getCenterY() * mImgHeight;
91             mToScr.mapPoints(mTmp);
92 
93             return mTmp[0];
94         }
95 
96         @Override
getCenterY()97         public float getCenterY() {
98             mTmp[0] = mOval.getCenterX() * mImgWidth;
99             mTmp[1] = mOval.getCenterY() * mImgHeight;
100             mToScr.mapPoints(mTmp);
101             return mTmp[1];
102         }
103 
104         @Override
getRadiusX()105         public float getRadiusX() {
106             mTmp[0] = mOval.getRadiusX() * mImgWidth;
107             mTmp[1] = mOval.getRadiusY() * mImgHeight;
108             mToScr.mapVectors(mTmp);
109             return Math.abs(mTmp[0]);
110         }
111 
112         @Override
getRadiusY()113         public float getRadiusY() {
114             mTmp[0] = mOval.getRadiusX() * mImgWidth;
115             mTmp[1] = mOval.getRadiusY() * mImgHeight;
116             mToScr.mapVectors(mTmp);
117             return Math.abs(mTmp[1]);
118         }
119 
120         @Override
setRadiusY(float y)121         public void setRadiusY(float y) {
122             mTmp[0] = mTmpRadiusX;
123             mTmp[1] = mTmpRadiusY = y;
124             mToImage.mapVectors(mTmp);
125             mOval.setRadiusX(mTmp[0] / mImgWidth);
126             mOval.setRadiusY(mTmp[1] / mImgHeight);
127         }
128 
129         @Override
setRadiusX(float x)130         public void setRadiusX(float x) {
131             mTmp[0] = mTmpRadiusX = x;
132             mTmp[1] = mTmpRadiusY;
133             mToImage.mapVectors(mTmp);
134             mOval.setRadiusX(mTmp[0] / mImgWidth);
135             mOval.setRadiusY(mTmp[1] / mImgHeight);
136         }
137     }
138 
139     @Override
onTouchEvent(MotionEvent event)140     public boolean onTouchEvent(MotionEvent event) {
141         int w = MasterImage.getImage().getOriginalBounds().width();
142         int h = MasterImage.getImage().getOriginalBounds().height();
143         int mask = event.getActionMasked();
144         if (mActiveHandle == -1) {
145             if (MotionEvent.ACTION_DOWN != mask) {
146                 return super.onTouchEvent(event);
147             }
148             if (event.getPointerCount() == 1) {
149                 mActiveHandle = mElipse.getCloseHandle(event.getX(), event.getY());
150             }
151             if (mActiveHandle == -1) {
152                 return super.onTouchEvent(event);
153             }
154         } else {
155             switch (mask) {
156                 case MotionEvent.ACTION_UP:
157                     mActiveHandle = -1;
158                     break;
159                 case MotionEvent.ACTION_DOWN:
160                     break;
161             }
162         }
163         float x = event.getX();
164         float y = event.getY();
165 
166         mElipse.setScrImageInfo(new Matrix(),
167                 MasterImage.getImage().getOriginalBounds());
168 
169         boolean didComputeEllipses = false;
170         switch (mask) {
171             case (MotionEvent.ACTION_DOWN):
172                 mElipse.actionDown(x, y, mScreenOval);
173                 break;
174             case (MotionEvent.ACTION_UP):
175             case (MotionEvent.ACTION_MOVE):
176 
177                 mElipse.actionMove(mActiveHandle, x, y, mScreenOval);
178                 setRepresentation(mVignetteRep);
179                 didComputeEllipses = true;
180                 break;
181         }
182         if (!didComputeEllipses) {
183             computeEllipses();
184         }
185         invalidate();
186         return true;
187     }
188 
setRepresentation(FilterVignetteRepresentation vignetteRep)189     public void setRepresentation(FilterVignetteRepresentation vignetteRep) {
190         mVignetteRep = vignetteRep;
191         mScreenOval.setImageOval(mVignetteRep);
192         computeEllipses();
193     }
194 
computeEllipses()195     public void computeEllipses() {
196         if (mVignetteRep == null) {
197             return;
198         }
199         float w = MasterImage.getImage().getOriginalBounds().width();
200         float h = MasterImage.getImage().getOriginalBounds().height();
201         Matrix toImg = getScreenToImageMatrix(false);
202         Matrix toScr = new Matrix();
203         toImg.invert(toScr);
204         mScreenOval.setTransform(toScr, toImg, (int) w, (int) h);
205 
206         mElipse.setCenter(mScreenOval.getCenterX(), mScreenOval.getCenterY());
207         mElipse.setRadius(mScreenOval.getRadiusX(), mScreenOval.getRadiusY());
208 
209         mEditorVignette.commitLocalRepresentation();
210     }
211 
setEditor(EditorVignette editorVignette)212     public void setEditor(EditorVignette editorVignette) {
213         mEditorVignette = editorVignette;
214     }
215 
216     @Override
onSizeChanged(int w, int h, int oldw, int oldh)217     public void onSizeChanged(int w, int h, int oldw, int oldh) {
218         super.onSizeChanged(w, h, oldw, oldh);
219         computeEllipses();
220     }
221 
222     @Override
onDraw(Canvas canvas)223     public void onDraw(Canvas canvas) {
224         super.onDraw(canvas);
225         if (mVignetteRep == null) {
226             return;
227         }
228         float w = MasterImage.getImage().getOriginalBounds().width();
229         float h = MasterImage.getImage().getOriginalBounds().height();
230         Matrix toImg = getScreenToImageMatrix(false);
231         Matrix toScr = new Matrix();
232         toImg.invert(toScr);
233         mScreenOval.setTransform(toScr, toImg, (int) w, (int) h);
234         mElipse.setCenter(mScreenOval.getCenterX(), mScreenOval.getCenterY());
235         mElipse.setRadius(mScreenOval.getRadiusX(), mScreenOval.getRadiusY());
236 
237         mElipse.draw(canvas);
238     }
239 
240 }
241