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