• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.Canvas;
21 import android.graphics.Color;
22 import android.graphics.Matrix;
23 import android.graphics.Paint;
24 import android.graphics.RadialGradient;
25 import android.graphics.Rect;
26 import android.graphics.RectF;
27 import android.graphics.Shader;
28 import android.util.Log;
29 
30 import com.android.gallery3d.R;
31 
32 public class EclipseControl {
33     private float mCenterX = Float.NaN;
34     private float mCenterY = 0;
35     private float mRadiusX = 200;
36     private float mRadiusY = 300;
37     private static int MIN_TOUCH_DIST = 80;// should be a resource & in dips
38     private static String LOGTAG = "EclipseControl";
39     private float[] handlex = new float[9];
40     private float[] handley = new float[9];
41     private int mSliderColor;
42     private int mCenterDotSize = 40;
43     private float mDownX;
44     private float mDownY;
45     private float mDownCenterX;
46     private float mDownCenterY;
47     private float mDownRadiusX;
48     private float mDownRadiusY;
49     private Matrix mScrToImg;
50 
51     private boolean mShowReshapeHandles = true;
52     public final static int HAN_CENTER = 0;
53     public final static int HAN_NORTH = 7;
54     public final static int HAN_NE = 8;
55     public final static int HAN_EAST = 1;
56     public final static int HAN_SE = 2;
57     public final static int HAN_SOUTH = 3;
58     public final static int HAN_SW = 4;
59     public final static int HAN_WEST = 5;
60     public final static int HAN_NW = 6;
61     private Rect mImageBounds;
62 
EclipseControl(Context context)63     public EclipseControl(Context context) {
64         mSliderColor = Color.WHITE;
65     }
66 
setRadius(float x, float y)67     public void setRadius(float x, float y) {
68         mRadiusX = x;
69         mRadiusY = y;
70     }
71 
setCenter(float x, float y)72     public void setCenter(float x, float y) {
73         mCenterX = x;
74         mCenterY = y;
75     }
76 
getCloseHandle(float x, float y)77     public int getCloseHandle(float x, float y) {
78         float min = Float.MAX_VALUE;
79         int handle = -1;
80         for (int i = 0; i < handlex.length; i++) {
81             float dx = handlex[i] - x;
82             float dy = handley[i] - y;
83             float dist = dx * dx + dy * dy;
84             if (dist < min) {
85                 min = dist;
86                 handle = i;
87             }
88         }
89 
90         if (min < MIN_TOUCH_DIST * MIN_TOUCH_DIST) {
91             return handle;
92         }
93         for (int i = 0; i < handlex.length; i++) {
94             float dx = handlex[i] - x;
95             float dy = handley[i] - y;
96             float dist = (float) Math.sqrt(dx * dx + dy * dy);
97         }
98 
99         return -1;
100     }
101 
setScrImageInfo(Matrix scrToImg, Rect imageBounds)102     public void setScrImageInfo(Matrix scrToImg, Rect imageBounds) {
103         mScrToImg = scrToImg;
104         mImageBounds = new Rect(imageBounds);
105     }
106 
centerIsOutside(float x1, float y1)107     private boolean centerIsOutside(float x1, float y1) {
108         return (!mImageBounds.contains((int) x1, (int) y1));
109     }
110 
actionDown(float x, float y, Oval oval)111     public void actionDown(float x, float y, Oval oval)  {
112         float[] point = new float[]{
113                 x, y};
114         mScrToImg.mapPoints(point);
115         mDownX = point[0];
116         mDownY = point[1];
117         mDownCenterX = oval.getCenterX();
118         mDownCenterY = oval.getCenterY();
119         mDownRadiusX = oval.getRadiusX();
120         mDownRadiusY = oval.getRadiusY();
121     }
122 
123 
actionMove(int handle, float x, float y, Oval oval)124     public void actionMove(int handle, float x, float y, Oval oval) {
125         float[] point = new float[]{
126                 x, y};
127         mScrToImg.mapPoints(point);
128         x = point[0];
129         y = point[1];
130 
131         // Test if the matrix is swapping x and y
132         point[0] = 0;
133         point[1] = 1;
134         mScrToImg.mapVectors(point);
135         boolean swapxy = (point[0] > 0.0f);
136 
137         int sign = 1;
138         switch (handle) {
139             case HAN_CENTER:
140                 float ctrdx = mDownX - mDownCenterX;
141                 float ctrdy = mDownY - mDownCenterY;
142                 if (centerIsOutside(x - ctrdx, y - ctrdy)) {
143                     break;
144                 }
145                 oval.setCenter((x - ctrdx), (y - ctrdy));
146                 // setRepresentation(mVignetteRep);
147                 break;
148             case HAN_NORTH:
149                 sign = -1;
150             case HAN_SOUTH:
151                 if (swapxy) {
152                     float raddx = mDownRadiusY - Math.abs(mDownX - mDownCenterY);
153                     oval.setRadiusY(Math.abs(x - oval.getCenterY() + sign * raddx));
154                 } else {
155                     float raddy = mDownRadiusY - Math.abs(mDownY - mDownCenterY);
156                     oval.setRadiusY(Math.abs(y - oval.getCenterY() + sign * raddy));
157                 }
158                 break;
159             case HAN_EAST:
160                 sign = -1;
161             case HAN_WEST:
162                 if (swapxy) {
163                     float raddy = mDownRadiusX - Math.abs(mDownY - mDownCenterX);
164                     oval.setRadiusX(Math.abs(y - oval.getCenterX() + sign * raddy));
165                 } else {
166                     float raddx = mDownRadiusX - Math.abs(mDownX - mDownCenterX);
167                     oval.setRadiusX(Math.abs(x - oval.getCenterX() -  sign * raddx));
168                 }
169                 break;
170             case HAN_SE:
171             case HAN_NE:
172             case HAN_SW:
173             case HAN_NW:
174                 float sin45 = (float) Math.sin(45);
175                 float dr = (mDownRadiusX + mDownRadiusY) * sin45;
176                 float ctr_dx = mDownX - mDownCenterX;
177                 float ctr_dy = mDownY - mDownCenterY;
178                 float downRad = Math.abs(ctr_dx) + Math.abs(ctr_dy) - dr;
179                 float rx = oval.getRadiusX();
180                 float ry = oval.getRadiusY();
181                 float r = (Math.abs(rx) + Math.abs(ry)) * sin45;
182                 float dx = x - oval.getCenterX();
183                 float dy = y - oval.getCenterY();
184                 float nr = Math.abs(Math.abs(dx) + Math.abs(dy) - downRad);
185                 oval.setRadius((rx * nr / r), (ry * nr / r));
186 
187                 break;
188         }
189     }
190 
paintGrayPoint(Canvas canvas, float x, float y)191     public void paintGrayPoint(Canvas canvas, float x, float y) {
192         if (Float.isNaN(x)) {
193             return;
194         }
195 
196         Paint paint = new Paint();
197 
198         paint.setStyle(Paint.Style.FILL);
199         paint.setColor(Color.BLUE);
200         int[] colors3 = new int[]{
201                 Color.GRAY, Color.LTGRAY, 0x66000000, 0};
202         RadialGradient g = new RadialGradient(x, y, mCenterDotSize, colors3, new float[]{
203                 0, .3f, .31f, 1}, Shader.TileMode.CLAMP);
204         paint.setShader(g);
205         canvas.drawCircle(x, y, mCenterDotSize, paint);
206     }
207 
paintPoint(Canvas canvas, float x, float y)208     public void paintPoint(Canvas canvas, float x, float y) {
209         if (Float.isNaN(x)) {
210             return;
211         }
212 
213         Paint paint = new Paint();
214 
215         paint.setStyle(Paint.Style.FILL);
216         paint.setColor(Color.BLUE);
217         int[] colors3 = new int[]{
218                 mSliderColor, mSliderColor, 0x66000000, 0};
219         RadialGradient g = new RadialGradient(x, y, mCenterDotSize, colors3, new float[]{
220                 0, .3f, .31f, 1}, Shader.TileMode.CLAMP);
221         paint.setShader(g);
222         canvas.drawCircle(x, y, mCenterDotSize, paint);
223     }
224 
paintRadius(Canvas canvas, float cx, float cy, float rx, float ry)225     void paintRadius(Canvas canvas, float cx, float cy, float rx, float ry) {
226         if (Float.isNaN(cx)) {
227             return;
228         }
229         int mSliderColor = 0xFF33B5E5;
230         Paint paint = new Paint();
231         RectF rect = new RectF(cx - rx, cy - ry, cx + rx, cy + ry);
232         paint.setAntiAlias(true);
233         paint.setStyle(Paint.Style.STROKE);
234         paint.setStrokeWidth(6);
235         paint.setColor(Color.BLACK);
236         paintOvallines(canvas, rect, paint, cx, cy, rx, ry);
237 
238         paint.setStrokeWidth(3);
239         paint.setColor(Color.WHITE);
240         paintOvallines(canvas, rect, paint, cx, cy, rx, ry);
241     }
242 
paintOvallines( Canvas canvas, RectF rect, Paint paint, float cx, float cy, float rx, float ry)243     public void paintOvallines(
244             Canvas canvas, RectF rect, Paint paint, float cx, float cy, float rx, float ry) {
245         canvas.drawOval(rect, paint);
246         float da = 4;
247         float arclen = da + da;
248         if (mShowReshapeHandles) {
249             paint.setStyle(Paint.Style.STROKE);
250 
251             for (int i = 0; i < 361; i += 90) {
252                 float dx = rx + 10;
253                 float dy = ry + 10;
254                 rect.left = cx - dx;
255                 rect.top = cy - dy;
256                 rect.right = cx + dx;
257                 rect.bottom = cy + dy;
258                 canvas.drawArc(rect, i - da, arclen, false, paint);
259                 dx = rx - 10;
260                 dy = ry - 10;
261                 rect.left = cx - dx;
262                 rect.top = cy - dy;
263                 rect.right = cx + dx;
264                 rect.bottom = cy + dy;
265                 canvas.drawArc(rect, i - da, arclen, false, paint);
266             }
267         }
268         da *= 2;
269         paint.setStyle(Paint.Style.FILL);
270 
271         for (int i = 45; i < 361; i += 90) {
272             double angle = Math.PI * i / 180.;
273             float x = cx + (float) (rx * Math.cos(angle));
274             float y = cy + (float) (ry * Math.sin(angle));
275             canvas.drawRect(x - da, y - da, x + da, y + da, paint);
276         }
277         paint.setStyle(Paint.Style.STROKE);
278         rect.left = cx - rx;
279         rect.top = cy - ry;
280         rect.right = cx + rx;
281         rect.bottom = cy + ry;
282     }
283 
fillHandles(Canvas canvas, float cx, float cy, float rx, float ry)284     public void fillHandles(Canvas canvas, float cx, float cy, float rx, float ry) {
285         handlex[0] = cx;
286         handley[0] = cy;
287         int k = 1;
288 
289         for (int i = 0; i < 360; i += 45) {
290             double angle = Math.PI * i / 180.;
291 
292             float x = cx + (float) (rx * Math.cos(angle));
293             float y = cy + (float) (ry * Math.sin(angle));
294             handlex[k] = x;
295             handley[k] = y;
296 
297             k++;
298         }
299     }
300 
draw(Canvas canvas)301     public void draw(Canvas canvas) {
302         paintRadius(canvas, mCenterX, mCenterY, mRadiusX, mRadiusY);
303         fillHandles(canvas, mCenterX, mCenterY, mRadiusX, mRadiusY);
304         paintPoint(canvas, mCenterX, mCenterY);
305     }
306 
isUndefined()307     public boolean isUndefined() {
308         return Float.isNaN(mCenterX);
309     }
310 
setShowReshapeHandles(boolean showReshapeHandles)311     public void setShowReshapeHandles(boolean showReshapeHandles) {
312         this.mShowReshapeHandles = showReshapeHandles;
313     }
314 }
315