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
17package com.android.gallery3d.filtershow.state;
18
19import android.content.Context;
20import android.content.res.Resources;
21import android.graphics.*;
22import android.view.MotionEvent;
23import android.view.View;
24import android.widget.LinearLayout;
25import com.android.gallery3d.R;
26import com.android.gallery3d.filtershow.FilterShowActivity;
27import com.android.gallery3d.filtershow.category.SwipableView;
28import com.android.gallery3d.filtershow.filters.FilterRepresentation;
29import com.android.gallery3d.filtershow.imageshow.MasterImage;
30import com.android.gallery3d.filtershow.pipeline.ImagePreset;
31
32public class StateView extends View implements SwipableView {
33
34    private static final String LOGTAG = "StateView";
35    private Path mPath = new Path();
36    private Paint mPaint = new Paint();
37
38    public static int DEFAULT = 0;
39    public static int BEGIN = 1;
40    public static int END = 2;
41
42    public static int UP = 1;
43    public static int DOWN = 2;
44    public static int LEFT = 3;
45    public static int RIGHT = 4;
46
47    private int mType = DEFAULT;
48    private float mAlpha = 1.0f;
49    private String mText = "Default";
50    private float mTextSize = 32;
51    private static int sMargin = 16;
52    private static int sArrowHeight = 16;
53    private static int sArrowWidth = 8;
54    private float mStartTouchX = 0;
55    private float mStartTouchY = 0;
56    private float mDeleteSlope = 20;
57
58    private int mOrientation = LinearLayout.VERTICAL;
59    private int mDirection = DOWN;
60    private boolean mDuplicateButton;
61    private State mState;
62
63    private int mEndsBackgroundColor;
64    private int mEndsTextColor;
65    private int mBackgroundColor;
66    private int mTextColor;
67    private int mSelectedBackgroundColor;
68    private int mSelectedTextColor;
69    private Rect mTextBounds = new Rect();
70
71    public StateView(Context context) {
72        this(context, DEFAULT);
73    }
74
75    public StateView(Context context, int type) {
76        super(context);
77        mType = type;
78        Resources res = getResources();
79        mEndsBackgroundColor = res.getColor(R.color.filtershow_stateview_end_background);
80        mEndsTextColor = res.getColor(R.color.filtershow_stateview_end_text);
81        mBackgroundColor = res.getColor(R.color.filtershow_stateview_background);
82        mTextColor = res.getColor(R.color.filtershow_stateview_text);
83        mSelectedBackgroundColor = res.getColor(R.color.filtershow_stateview_selected_background);
84        mSelectedTextColor = res.getColor(R.color.filtershow_stateview_selected_text);
85        mTextSize = res.getDimensionPixelSize(R.dimen.state_panel_text_size);
86    }
87
88    public String getText() {
89        return mText;
90    }
91
92    public void setText(String text) {
93        mText = text;
94        invalidate();
95    }
96
97    public void setType(int type) {
98        mType = type;
99        invalidate();
100    }
101
102    @Override
103    public void setSelected(boolean value) {
104        super.setSelected(value);
105        if (!value) {
106            mDuplicateButton = false;
107        }
108        invalidate();
109    }
110
111    public void drawText(Canvas canvas) {
112        if (mText == null) {
113            return;
114        }
115        mPaint.reset();
116        if (isSelected()) {
117            mPaint.setColor(mSelectedTextColor);
118        } else {
119            mPaint.setColor(mTextColor);
120        }
121        if (mType == BEGIN) {
122            mPaint.setColor(mEndsTextColor);
123        }
124        mPaint.setTypeface(Typeface.DEFAULT_BOLD);
125        mPaint.setAntiAlias(true);
126        mPaint.setTextSize(mTextSize);
127        mPaint.getTextBounds(mText, 0, mText.length(), mTextBounds);
128        int x = (canvas.getWidth() - mTextBounds.width()) / 2;
129        int y = mTextBounds.height() + (canvas.getHeight() - mTextBounds.height()) / 2;
130        canvas.drawText(mText, x, y, mPaint);
131    }
132
133    public void onDraw(Canvas canvas) {
134        canvas.drawARGB(0, 0, 0, 0);
135        mPaint.reset();
136        mPath.reset();
137
138        float w = canvas.getWidth();
139        float h = canvas.getHeight();
140        float r = sArrowHeight;
141        float d = sArrowWidth;
142
143        if (mOrientation == LinearLayout.HORIZONTAL) {
144            drawHorizontalPath(w, h, r, d);
145        } else {
146            if (mDirection == DOWN) {
147                drawVerticalDownPath(w, h, r, d);
148            } else {
149                drawVerticalPath(w, h, r, d);
150            }
151        }
152
153        if (mType == DEFAULT || mType == END) {
154            if (mDuplicateButton) {
155                mPaint.setARGB(255, 200, 0, 0);
156            } else if (isSelected()) {
157                mPaint.setColor(mSelectedBackgroundColor);
158            } else {
159                mPaint.setColor(mBackgroundColor);
160            }
161        } else {
162            mPaint.setColor(mEndsBackgroundColor);
163        }
164        canvas.drawPath(mPath, mPaint);
165        drawText(canvas);
166    }
167
168    private void drawHorizontalPath(float w, float h, float r, float d) {
169        if (this.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
170            mPath.moveTo(w, 0);
171            if (mType == END) {
172                mPath.lineTo(0, 0);
173                mPath.lineTo(0, h);
174            } else {
175                mPath.lineTo(d, 0);
176                mPath.lineTo(d, r);
177                mPath.lineTo(0, r + d);
178                mPath.lineTo(d, r + d + r);
179                mPath.lineTo(d, h);
180            }
181            mPath.lineTo(w, h);
182            if (mType != BEGIN) {
183                mPath.lineTo(w, r + d + r);
184                mPath.lineTo(w - d, r + d);
185                mPath.lineTo(w, r);
186            }
187        } else {
188            mPath.moveTo(0, 0);
189            if (mType == END) {
190                mPath.lineTo(w, 0);
191                mPath.lineTo(w, h);
192            } else {
193                mPath.lineTo(w - d, 0);
194                mPath.lineTo(w - d, r);
195                mPath.lineTo(w, r + d);
196                mPath.lineTo(w - d, r + d + r);
197                mPath.lineTo(w - d, h);
198            }
199            mPath.lineTo(0, h);
200            if (mType != BEGIN) {
201                mPath.lineTo(0, r + d + r);
202                mPath.lineTo(d, r + d);
203                mPath.lineTo(0, r);
204            }
205        }
206        mPath.close();
207    }
208
209    private void drawVerticalPath(float w, float h, float r, float d) {
210        if (mType == BEGIN) {
211            mPath.moveTo(0, 0);
212            mPath.lineTo(w, 0);
213        } else {
214            mPath.moveTo(0, d);
215            mPath.lineTo(r, d);
216            mPath.lineTo(r + d, 0);
217            mPath.lineTo(r + d + r, d);
218            mPath.lineTo(w, d);
219        }
220        mPath.lineTo(w, h);
221        if (mType != END) {
222            mPath.lineTo(r + d + r, h);
223            mPath.lineTo(r + d, h - d);
224            mPath.lineTo(r, h);
225        }
226        mPath.lineTo(0, h);
227        mPath.close();
228    }
229
230    private void drawVerticalDownPath(float w, float h, float r, float d) {
231        mPath.moveTo(0, 0);
232        if (mType != BEGIN) {
233            mPath.lineTo(r, 0);
234            mPath.lineTo(r + d, d);
235            mPath.lineTo(r + d + r, 0);
236        }
237        mPath.lineTo(w, 0);
238
239        if (mType != END) {
240            mPath.lineTo(w, h - d);
241
242            mPath.lineTo(r + d + r, h - d);
243            mPath.lineTo(r + d, h);
244            mPath.lineTo(r, h - d);
245
246            mPath.lineTo(0, h - d);
247        } else {
248            mPath.lineTo(w, h);
249            mPath.lineTo(0, h);
250        }
251
252        mPath.close();
253    }
254
255    public void setBackgroundAlpha(float alpha) {
256        if (mType == BEGIN) {
257            return;
258        }
259        mAlpha = alpha;
260        setAlpha(alpha);
261        invalidate();
262    }
263
264    public float getBackgroundAlpha() {
265        return mAlpha;
266    }
267
268    public void setOrientation(int orientation) {
269        mOrientation = orientation;
270    }
271
272    public void setDuplicateButton(boolean b) {
273        mDuplicateButton = b;
274        invalidate();
275    }
276
277    public State getState() {
278        return mState;
279    }
280
281    public void setState(State state) {
282        mState = state;
283        mText = mState.getText().toUpperCase();
284        mType = mState.getType();
285        invalidate();
286    }
287
288    public void resetPosition() {
289        setTranslationX(0);
290        setTranslationY(0);
291        setBackgroundAlpha(1.0f);
292    }
293
294    public boolean isDraggable() {
295        return mState.isDraggable();
296    }
297
298    @Override
299    public void delete() {
300        FilterShowActivity activity = (FilterShowActivity) getContext();
301        FilterRepresentation representation = getState().getFilterRepresentation();
302        activity.removeFilterRepresentation(representation);
303    }
304
305    @Override
306    public boolean onTouchEvent(MotionEvent event) {
307        boolean ret = super.onTouchEvent(event);
308        FilterShowActivity activity = (FilterShowActivity) getContext();
309
310        if (event.getActionMasked() == MotionEvent.ACTION_UP) {
311            activity.startTouchAnimation(this, event.getX(), event.getY());
312        }
313        if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
314            mStartTouchY = event.getY();
315            mStartTouchX = event.getX();
316            if (mType == BEGIN) {
317                MasterImage.getImage().setShowsOriginal(true);
318            }
319        }
320        if (event.getActionMasked() == MotionEvent.ACTION_UP
321            || event.getActionMasked() == MotionEvent.ACTION_CANCEL) {
322            setTranslationX(0);
323            setTranslationY(0);
324            MasterImage.getImage().setShowsOriginal(false);
325            if (mType != BEGIN && event.getActionMasked() == MotionEvent.ACTION_UP) {
326                setSelected(true);
327                FilterRepresentation representation = getState().getFilterRepresentation();
328                MasterImage image = MasterImage.getImage();
329                ImagePreset preset = image != null ? image.getCurrentPreset() : null;
330                if (getTranslationY() == 0
331                        && image != null && preset != null
332                        && representation != image.getCurrentFilterRepresentation()
333                        && preset.getRepresentation(representation) != null) {
334                    activity.showRepresentation(representation);
335                    setSelected(false);
336                }
337            }
338        }
339        if (mType != BEGIN && event.getActionMasked() == MotionEvent.ACTION_MOVE) {
340            float delta = event.getY() - mStartTouchY;
341            if (Math.abs(delta) > mDeleteSlope) {
342                activity.setHandlesSwipeForView(this, mStartTouchX, mStartTouchY);
343            }
344        }
345        return true;
346    }
347}
348