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