1/*
2 * Copyright (C) 2010 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.videoeditor.widgets;
18
19import com.android.videoeditor.service.MovieMediaItem;
20import com.android.videoeditor.service.MovieOverlay;
21import com.android.videoeditor.util.ImageUtils;
22import com.android.videoeditor.R;
23
24import android.content.Context;
25import android.content.res.Resources;
26import android.graphics.Canvas;
27import android.graphics.drawable.Drawable;
28import android.util.AttributeSet;
29import android.view.GestureDetector;
30import android.view.MotionEvent;
31import android.widget.ImageView;
32
33/**
34 * Overlay view
35 */
36public class OverlayView extends ImageView {
37    // States
38    // No visible state
39    public static final int STATE_STUB = 0;
40    // Display an "Add" button state
41    public static final int STATE_ADD_BUTTON = 1;
42    // The overlay is displayed
43    public static final int STATE_OVERLAY = 2;
44
45    // Instance variables
46    private final Drawable mArrowLeft;
47    private final Drawable mArrowRight;
48    private final GestureDetector mSimpleGestureDetector;
49    private ItemMoveGestureListener mGestureListener;
50    private int mState;
51    private boolean mLongPressMove;
52    private MotionEvent mStartScrollEvent;
53
54    public OverlayView(Context context, AttributeSet attrs, int defStyle) {
55        super(context, attrs, defStyle);
56
57        mSimpleGestureDetector = new GestureDetector(context,
58                new GestureDetector.SimpleOnGestureListener() {
59                    @Override
60                    public boolean onSingleTapConfirmed(MotionEvent e) {
61                        if (mGestureListener != null) {
62                            return mGestureListener.onSingleTapConfirmed(OverlayView.this, -1, e);
63                        } else {
64                            return false;
65                        }
66                    }
67
68                    @Override
69                    public void onLongPress(MotionEvent e) {
70                        if (mGestureListener == null) {
71                            return;
72                        }
73
74                        mGestureListener.onLongPress(OverlayView.this, e);
75
76                        if (mState == STATE_OVERLAY) {
77                            if (mGestureListener.onMoveBegin(OverlayView.this, e)) {
78                                mLongPressMove = true;
79                                // Draw the 'move' arrows
80                                invalidate();
81
82                                mStartScrollEvent = MotionEvent.obtain(e);
83                                getParent().requestDisallowInterceptTouchEvent(true);
84                            }
85                        }
86                    }
87                });
88
89        // Prepare the handle arrows
90        final Resources resources = getResources();
91        mArrowLeft = resources.getDrawable(R.drawable.ic_drag_clip_left);
92        mArrowRight = resources.getDrawable(R.drawable.ic_drag_clip_right);
93
94        mState = STATE_STUB;
95    }
96
97    public OverlayView(Context context, AttributeSet attrs) {
98        this(context, attrs, 0);
99    }
100
101    public OverlayView(Context context) {
102        this(context, null, 0);
103    }
104
105    /**
106     * @return The state
107     */
108    public int getState() {
109        return mState;
110    }
111
112    /**
113     * @param state The state
114     */
115    public void setState(int state) {
116        mState = state;
117
118        switch (mState) {
119            case STATE_STUB: {
120                setBackgroundDrawable(null);
121                setImageDrawable(null);
122                break;
123            }
124
125            case STATE_ADD_BUTTON: {
126                setBackgroundDrawable(null);
127                setImageResource(R.drawable.ic_menu_add_title);
128                break;
129            }
130
131            case STATE_OVERLAY: {
132                setBackgroundResource(R.drawable.timeline_item_selector);
133                setImageDrawable(null);
134                break;
135            }
136
137            default: {
138                break;
139            }
140        }
141    }
142
143    /**
144     * @param listener The gesture listener
145     */
146    public void setGestureListener(ItemMoveGestureListener listener) {
147        mGestureListener = listener;
148    }
149
150    @Override
151    public void setSelected(boolean selected) {
152        super.setSelected(selected);
153
154        if (!selected) {
155            if (mState == STATE_ADD_BUTTON) {
156                setState(STATE_STUB);
157            }
158        }
159    }
160
161    @Override
162    public boolean onTouchEvent(MotionEvent ev) {
163        mSimpleGestureDetector.onTouchEvent(ev);
164
165        super.onTouchEvent(ev);
166        switch (ev.getAction()) {
167            case MotionEvent.ACTION_MOVE: {
168                if (mLongPressMove && mGestureListener != null) {
169                    mGestureListener.onMove(this, mStartScrollEvent, ev);
170                }
171                break;
172            }
173
174            case MotionEvent.ACTION_UP:
175            case MotionEvent.ACTION_CANCEL: {
176                if (mLongPressMove) {
177                    mLongPressMove = false;
178                    // Hide the 'move' arrows
179                    invalidate();
180
181                    if (mGestureListener != null) {
182                        mGestureListener.onMoveEnd(this);
183                    }
184                }
185                break;
186            }
187        }
188
189        return true;
190    }
191
192    @Override
193    public void onDraw(Canvas canvas) {
194        super.onDraw(canvas);
195
196        switch (mState) {
197            case STATE_STUB: {
198                break;
199            }
200
201            case STATE_ADD_BUTTON: {
202                break;
203            }
204
205            case STATE_OVERLAY: {
206                final MovieMediaItem mediaItem = (MovieMediaItem)getTag();
207                if (mediaItem != null) {
208                    final MovieOverlay overlay = mediaItem.getOverlay();
209                    if (overlay != null) {
210                        ImageUtils.buildOverlayPreview(getContext(), canvas, overlay.getType(),
211                                overlay.getTitle(), overlay.getSubtitle(),
212                                getPaddingLeft(), getPaddingTop(),
213                                getWidth() - getPaddingLeft() - getPaddingRight(),
214                                getHeight() - getPaddingTop() - getPaddingBottom());
215                    }
216                }
217                break;
218            }
219
220            default: {
221                break;
222            }
223        }
224
225        if (mLongPressMove) {
226            final int halfWidth = getWidth() / 2;
227            mArrowLeft.setBounds(halfWidth - 4 - mArrowLeft.getIntrinsicWidth(), getPaddingTop(),
228                    halfWidth - 4, getPaddingTop() + mArrowLeft.getIntrinsicHeight());
229            mArrowLeft.draw(canvas);
230
231            mArrowRight.setBounds(halfWidth + 4, getPaddingTop(), halfWidth + 4
232                    + mArrowRight.getIntrinsicWidth(), getPaddingTop()
233                    + mArrowRight.getIntrinsicHeight());
234            mArrowRight.draw(canvas);
235        }
236    }
237}
238