1package com.android.gallery3d.filtershow.imageshow;
2/*
3 * Copyright (C) 2013 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18import android.content.Context;
19import android.content.res.Resources;
20import android.graphics.Canvas;
21import android.graphics.Matrix;
22import android.util.AttributeSet;
23import android.view.MotionEvent;
24
25import com.android.gallery3d.R;
26import com.android.gallery3d.filtershow.editors.EditorGrad;
27import com.android.gallery3d.filtershow.filters.FilterGradRepresentation;
28
29public class ImageGrad extends ImageShow {
30    private static final String LOGTAG = "ImageGrad";
31    private FilterGradRepresentation mGradRep;
32    private EditorGrad mEditorGrad;
33    private float mMinTouchDist;
34    private int mActiveHandle = -1;
35    private GradControl mEllipse;
36
37    Matrix mToScr = new Matrix();
38    float[] mPointsX = new float[FilterGradRepresentation.MAX_POINTS];
39    float[] mPointsY = new float[FilterGradRepresentation.MAX_POINTS];
40
41    public ImageGrad(Context context) {
42        super(context);
43        Resources res = context.getResources();
44        mMinTouchDist = res.getDimensionPixelSize(R.dimen.gradcontrol_min_touch_dist);
45        mEllipse = new GradControl(context);
46        mEllipse.setShowReshapeHandles(false);
47    }
48
49    public ImageGrad(Context context, AttributeSet attrs) {
50        super(context, attrs);
51        Resources res = context.getResources();
52        mMinTouchDist = res.getDimensionPixelSize(R.dimen.gradcontrol_min_touch_dist);
53        mEllipse = new GradControl(context);
54        mEllipse.setShowReshapeHandles(false);
55    }
56
57    @Override
58    public boolean onTouchEvent(MotionEvent event) {
59        int mask = event.getActionMasked();
60
61        if (mActiveHandle == -1) {
62            if (MotionEvent.ACTION_DOWN != mask) {
63                return super.onTouchEvent(event);
64            }
65            if (event.getPointerCount() == 1) {
66                mActiveHandle = mEllipse.getCloseHandle(event.getX(), event.getY());
67                if (mActiveHandle == -1) {
68                    float x = event.getX();
69                    float y = event.getY();
70                    float min_d = Float.MAX_VALUE;
71                    int pos = -1;
72                    for (int i = 0; i < mPointsX.length; i++) {
73                        if (mPointsX[i] == -1) {
74                            continue;
75                        }
76                        float d = (float) Math.hypot(x - mPointsX[i], y - mPointsY[i]);
77                        if ( min_d > d) {
78                            min_d = d;
79                            pos = i;
80                        }
81                    }
82                    if (min_d > mMinTouchDist){
83                        pos = -1;
84                    }
85
86                    if (pos != -1) {
87                        mGradRep.setSelectedPoint(pos);
88                        resetImageCaches(this);
89                        mEditorGrad.updateSeekBar(mGradRep);
90                        mEditorGrad.commitLocalRepresentation();
91                        invalidate();
92                    }
93                }
94            }
95            if (mActiveHandle == -1) {
96                return super.onTouchEvent(event);
97            }
98        } else {
99            switch (mask) {
100                case MotionEvent.ACTION_UP: {
101
102                    mActiveHandle = -1;
103                    break;
104                }
105                case MotionEvent.ACTION_DOWN: {
106                    break;
107                }
108            }
109        }
110        float x = event.getX();
111        float y = event.getY();
112
113        mEllipse.setScrImageInfo(getScreenToImageMatrix(true),
114                MasterImage.getImage().getOriginalBounds());
115
116        switch (mask) {
117            case (MotionEvent.ACTION_DOWN): {
118                mEllipse.actionDown(x, y, mGradRep);
119                break;
120            }
121            case (MotionEvent.ACTION_UP):
122            case (MotionEvent.ACTION_MOVE): {
123                mEllipse.actionMove(mActiveHandle, x, y, mGradRep);
124                setRepresentation(mGradRep);
125                break;
126            }
127        }
128        invalidate();
129        mEditorGrad.commitLocalRepresentation();
130        return true;
131    }
132
133    public void setRepresentation(FilterGradRepresentation pointRep) {
134        mGradRep = pointRep;
135        Matrix toImg = getScreenToImageMatrix(false);
136
137        toImg.invert(mToScr);
138
139        float[] c1 = new float[] { mGradRep.getPoint1X(), mGradRep.getPoint1Y() };
140        float[] c2 = new float[] { mGradRep.getPoint2X(), mGradRep.getPoint2Y() };
141
142        if (c1[0] == -1) {
143            float cx = MasterImage.getImage().getOriginalBounds().width() / 2;
144            float cy = MasterImage.getImage().getOriginalBounds().height() / 2;
145            float rx = Math.min(cx, cy) * .4f;
146
147            mGradRep.setPoint1(cx, cy-rx);
148            mGradRep.setPoint2(cx, cy+rx);
149            c1[0] = cx;
150            c1[1] = cy-rx;
151            mToScr.mapPoints(c1);
152            if (getWidth() != 0) {
153                mEllipse.setPoint1(c1[0], c1[1]);
154                c2[0] = cx;
155                c2[1] = cy+rx;
156                mToScr.mapPoints(c2);
157                mEllipse.setPoint2(c2[0], c2[1]);
158            }
159            mEditorGrad.commitLocalRepresentation();
160        } else {
161            mToScr.mapPoints(c1);
162            mToScr.mapPoints(c2);
163            mEllipse.setPoint1(c1[0], c1[1]);
164            mEllipse.setPoint2(c2[0], c2[1]);
165        }
166    }
167
168    public void drawOtherPoints(Canvas canvas) {
169        computCenterLocations();
170        for (int i = 0; i < mPointsX.length; i++) {
171            if (mPointsX[i] != -1) {
172                mEllipse.paintGrayPoint(canvas, mPointsX[i], mPointsY[i]);
173            }
174        }
175    }
176
177    public void computCenterLocations() {
178        int x1[] = mGradRep.getXPos1();
179        int y1[] = mGradRep.getYPos1();
180        int x2[] = mGradRep.getXPos2();
181        int y2[] = mGradRep.getYPos2();
182        int selected = mGradRep.getSelectedPoint();
183        boolean m[] = mGradRep.getMask();
184        float[] c = new float[2];
185        for (int i = 0; i < m.length; i++) {
186            if (selected == i || !m[i]) {
187                mPointsX[i] = -1;
188                continue;
189            }
190
191            c[0] = (x1[i]+x2[i])/2;
192            c[1] = (y1[i]+y2[i])/2;
193            mToScr.mapPoints(c);
194
195            mPointsX[i] = c[0];
196            mPointsY[i] = c[1];
197        }
198    }
199
200    public void setEditor(EditorGrad editorGrad) {
201        mEditorGrad = editorGrad;
202    }
203
204    @Override
205    public void onDraw(Canvas canvas) {
206        super.onDraw(canvas);
207        if (mGradRep == null) {
208            return;
209        }
210        setRepresentation(mGradRep);
211        mEllipse.draw(canvas);
212        drawOtherPoints(canvas);
213    }
214
215}
216