blob: 03f9852d195a9b1ee20978ff3212b6e14829b04e [file] [log] [blame]
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.videoeditor.widgets;
import java.util.List;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ActionMode;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import com.android.videoeditor.AlertDialogs;
import com.android.videoeditor.OverlayTitleEditor;
import com.android.videoeditor.VideoEditorActivity;
import com.android.videoeditor.service.ApiService;
import com.android.videoeditor.service.MovieMediaItem;
import com.android.videoeditor.service.MovieOverlay;
import com.android.videoeditor.service.VideoEditorProject;
import com.android.videoeditor.util.FileUtils;
import com.android.videoeditor.util.MediaItemUtils;
import com.android.videoeditor.R;
/**
* LinearLayout which displays overlays.
*/
public class OverlayLinearLayout extends LinearLayout {
// Logging
private static final String TAG = "OverlayLinearLayout";
// Dialog parameter ids
private static final String PARAM_DIALOG_MEDIA_ITEM_ID = "media_item_id";
// Default overlay duration
public static final long DEFAULT_TITLE_DURATION = 3000;
// Instance variables
private final ItemMoveGestureListener mOverlayGestureListener;
private final int mHalfParentWidth;
private final Handler mHandler;
private final int mHandleWidth;
private ActionMode mOverlayActionMode;
private boolean mPlaybackInProgress;
private VideoEditorProject mProject;
private HandleView mLeftHandle, mRightHandle;
private boolean mMoveLayoutPending;
private View mResizingView;
/**
* The overlay listener
*/
public interface OverlayLayoutListener {
/**
* Add a new overlay
*/
public void onAddOverlay();
}
/**
* The overlay action mode handler.
*/
private class OverlayActionModeCallback implements ActionMode.Callback {
// Instance variables
private final MovieMediaItem mMediaItem;
public OverlayActionModeCallback(MovieMediaItem mediaItem) {
mMediaItem = mediaItem;
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mOverlayActionMode = mode;
final Activity activity = (Activity) getContext();
activity.getMenuInflater().inflate(R.menu.overlay_mode_menu, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
final boolean enable = !ApiService.isProjectBeingEdited(mProject.getPath()) &&
!mPlaybackInProgress;
final MenuItem eomi = menu.findItem(R.id.action_edit_overlay);
eomi.setEnabled(enable);
final MenuItem romi = menu.findItem(R.id.action_remove_overlay);
romi.setEnabled(enable);
return true;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.action_edit_overlay: {
final Activity activity = (Activity) getContext();
final Intent intent = new Intent(activity, OverlayTitleEditor.class);
intent.putExtra(OverlayTitleEditor.PARAM_MEDIA_ITEM_ID, mMediaItem.getId());
final MovieOverlay overlay = mMediaItem.getOverlay();
intent.putExtra(OverlayTitleEditor.PARAM_OVERLAY_ID, overlay.getId());
intent.putExtra(OverlayTitleEditor.PARAM_OVERLAY_ATTRIBUTES,
overlay.buildUserAttributes());
activity.startActivityForResult(intent,
VideoEditorActivity.REQUEST_CODE_PICK_OVERLAY);
break;
}
case R.id.action_remove_overlay: {
final Bundle bundle = new Bundle();
bundle.putString(PARAM_DIALOG_MEDIA_ITEM_ID, mMediaItem.getId());
((Activity) getContext()).showDialog(
VideoEditorActivity.DIALOG_REMOVE_OVERLAY_ID, bundle);
break;
}
default: {
break;
}
}
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
final View overlayView = getOverlayView(mMediaItem.getId());
if (overlayView != null) {
selectView(overlayView, false);
}
mOverlayActionMode = null;
}
}
public OverlayLinearLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mOverlayGestureListener = new ItemMoveGestureListener() {
private MovieMediaItem mScrollMediaItem;
private MovieOverlay mScrollOverlay;
private long mScrollTotalDurationMs, mScrollMediaItemStartTime;
private boolean mScrolled;
@Override
public boolean onSingleTapConfirmed(View view, int area, MotionEvent e) {
if (mPlaybackInProgress) {
return false;
}
switch (((OverlayView)view).getState()) {
case OverlayView.STATE_STUB: {
unselectAllViews();
((OverlayView)view).setState(OverlayView.STATE_ADD_BUTTON);
break;
}
case OverlayView.STATE_ADD_BUTTON: {
final MovieMediaItem mediaItem = (MovieMediaItem)view.getTag();
final Intent intent = new Intent(getContext(), OverlayTitleEditor.class);
intent.putExtra(OverlayTitleEditor.PARAM_MEDIA_ITEM_ID, mediaItem.getId());
((Activity) getContext()).startActivityForResult(intent,
VideoEditorActivity.REQUEST_CODE_PICK_OVERLAY);
break;
}
case OverlayView.STATE_OVERLAY: {
if (!view.isSelected()) {
selectView(view, true);
}
break;
}
default: {
break;
}
}
return true;
}
@Override
public void onLongPress(View view, MotionEvent e) {
if (mPlaybackInProgress) {
return;
}
switch (((OverlayView)view).getState()) {
case OverlayView.STATE_STUB: {
break;
}
case OverlayView.STATE_ADD_BUTTON: {
break;
}
case OverlayView.STATE_OVERLAY: {
if (!view.isSelected()) {
selectView(view, true);
}
if (mOverlayActionMode == null) {
startActionMode(new OverlayActionModeCallback(
(MovieMediaItem)view.getTag()));
}
break;
}
default: {
break;
}
}
}
@Override
public boolean onMoveBegin(View view, MotionEvent e) {
if (mPlaybackInProgress) {
return false;
}
mScrollMediaItem = (MovieMediaItem)view.getTag();
mScrollMediaItemStartTime = mProject.getMediaItemBeginTime(mScrollMediaItem.getId());
mScrollOverlay = mScrollMediaItem.getOverlay();
// The duration of the timeline does not change while moving the Overlay
mScrollTotalDurationMs = mProject.computeDuration();
mRightHandle.setVisibility(View.GONE);
mScrolled = false;
return true;
}
@Override
public boolean onMove(View view, MotionEvent e1, MotionEvent e2) {
final int beginPos = (int)(view.getLeft() - mHalfParentWidth - e1.getX() +
e2.getX());
long startTimeMs = ((beginPos * mScrollTotalDurationMs) /
(getWidth() - (2 * mHalfParentWidth)));
if (startTimeMs <= mScrollMediaItemStartTime) {
startTimeMs = mScrollMediaItemStartTime;
} else if (startTimeMs + mScrollOverlay.getAppDuration() >
mScrollMediaItemStartTime + mScrollMediaItem.getAppTimelineDuration()) {
startTimeMs = mScrollMediaItemStartTime +
mScrollMediaItem.getAppTimelineDuration() - mScrollOverlay.getAppDuration();
}
mScrolled = true;
mScrollOverlay.setAppStartTime(startTimeMs - mScrollMediaItemStartTime +
mScrollMediaItem.getAppBoundaryBeginTime());
requestLayout();
return true;
}
@Override
public void onMoveEnd(View view) {
mRightHandle.setVisibility(View.VISIBLE);
if (mScrolled) {
mScrolled = false;
// Update the limits of the right handle
mRightHandle.setLimitReached(mScrollOverlay.getAppDuration() <=
MediaItemUtils.getMinimumMediaItemDuration(mScrollMediaItem),
mScrollOverlay.getAppStartTime() + mScrollOverlay.getAppDuration() >=
mScrollMediaItem.getAppBoundaryEndTime());
ApiService.setOverlayStartTime(getContext(), mProject.getPath(),
mScrollMediaItem.getId(), mScrollOverlay.getId(),
mScrollOverlay.getAppStartTime());
}
}
};
// Add the beginning timeline item
final View beginView = inflate(getContext(), R.layout.empty_timeline_item, null);
beginView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
unselectAllViews();
}
});
addView(beginView);
// Add the end timeline item
final View endView = inflate(getContext(), R.layout.empty_timeline_item, null);
endView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
unselectAllViews();
}
});
addView(endView);
mLeftHandle = (HandleView)inflate(getContext(), R.layout.left_handle_view, null);
addView(mLeftHandle);
mRightHandle = (HandleView)inflate(getContext(), R.layout.right_handle_view, null);
addView(mRightHandle);
mHandleWidth = (int)context.getResources().getDimension(R.dimen.handle_width);
// Compute half the width of the screen (and therefore the parent view)
final Display display = ((Activity)context).getWindowManager().getDefaultDisplay();
mHalfParentWidth = display.getWidth() / 2;
mHandler = new Handler();
setMotionEventSplittingEnabled(false);
}
public OverlayLinearLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public OverlayLinearLayout(Context context) {
this(context, null, 0);
}
/**
* @param project The project
*/
public void setProject(VideoEditorProject project) {
// Close the contextual action bar
if (mOverlayActionMode != null) {
mOverlayActionMode.finish();
mOverlayActionMode = null;
}
mLeftHandle.setVisibility(View.GONE);
mLeftHandle.setListener(null);
mRightHandle.setVisibility(View.GONE);
mRightHandle.setListener(null);
removeViews();
mProject = project;
}
/**
* @param inProgress true if playback is in progress
*/
public void setPlaybackInProgress(boolean inProgress) {
mPlaybackInProgress = inProgress;
// Don't allow the user to interact with the overlays while playback
// is in progress
if (inProgress && mOverlayActionMode != null) {
mOverlayActionMode.finish();
mOverlayActionMode = null;
}
}
/**
* Add all the media items
*
* @param mediaItems The list of media items
*/
public void addMediaItems(List<MovieMediaItem> mediaItems) {
if (mOverlayActionMode != null) {
mOverlayActionMode.finish();
mOverlayActionMode = null;
}
removeViews();
for (MovieMediaItem mediaItem : mediaItems) {
addMediaItem(mediaItem);
}
}
/**
* Add a new media item at the end of the timeline
*
* @param mediaItem The media item
* @return The view that was added
*/
private View addMediaItem(MovieMediaItem mediaItem) {
final OverlayView overlayView = (OverlayView)inflate(getContext(),
R.layout.overlay_item, null);
if (mediaItem.getOverlay() != null) {
overlayView.setState(OverlayView.STATE_OVERLAY);
} else {
overlayView.setState(OverlayView.STATE_STUB);
}
overlayView.setTag(mediaItem);
overlayView.setGestureListener(mOverlayGestureListener);
final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.FILL_PARENT);
addView(overlayView, getChildCount() - 1, lp);
if (mOverlayActionMode != null) {
mOverlayActionMode.invalidate();
}
requestLayout();
return overlayView;
}
/**
* Insert a new media item after the specified media item id
*
* @param mediaItem The media item
* @param afterMediaItemId The id of the media item preceding the media item
*/
public void insertMediaItem(MovieMediaItem mediaItem, String afterMediaItemId) {
final OverlayView overlayView = (OverlayView)inflate(getContext(),
R.layout.overlay_item, null);
if (mediaItem.getOverlay() != null) {
overlayView.setState(OverlayView.STATE_OVERLAY);
} else {
overlayView.setState(OverlayView.STATE_STUB);
}
overlayView.setTag(mediaItem);
overlayView.setGestureListener(mOverlayGestureListener);
int insertViewIndex;
if (afterMediaItemId != null) {
if ((insertViewIndex = getMediaItemViewIndex(afterMediaItemId)) == -1) {
Log.e(TAG, "Media item not found: " + afterMediaItemId);
return;
}
insertViewIndex++;
} else { // Insert at the beginning
insertViewIndex = 1;
}
final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.FILL_PARENT);
addView(overlayView, insertViewIndex, lp);
if (mOverlayActionMode != null) {
mOverlayActionMode.invalidate();
}
requestLayout();
}
/**
* Update media item
*
* @param mediaItem The media item
*/
public void updateMediaItem(MovieMediaItem mediaItem) {
final String mediaItemId = mediaItem.getId();
final int childrenCount = getChildCount();
for (int i = 0; i < childrenCount; i++) {
final View childView = getChildAt(i);
final MovieMediaItem mi = (MovieMediaItem)childView.getTag();
if (mi != null && mediaItemId.equals(mi.getId())) {
if (mediaItem != mi) {
// The media item is a new instance
childView.setTag(mediaItem);
}
break;
}
}
requestLayout();
invalidate();
}
/**
* Remove a media item
*
* @param mediaItemId The media item id
* @return The view which was removed
*/
public View removeMediaItem(String mediaItemId) {
final int childrenCount = getChildCount();
for (int i = 0; i < childrenCount; i++) {
final View childView = getChildAt(i);
final MovieMediaItem mediaItem = (MovieMediaItem)childView.getTag();
if (mediaItem != null && mediaItem.getId().equals(mediaItemId)) {
removeViewAt(i);
requestLayout();
return childView;
}
}
return null;
}
/**
* A new overlay was added
*
* @param mediaItemId The media item which owns the overlay
* @param overlay The overlay which was added
*/
public void addOverlay(String mediaItemId, MovieOverlay overlay) {
final OverlayView view = (OverlayView)getOverlayView(mediaItemId);
if (view == null) {
Log.e(TAG, "addOverlay: Media item not found: " + mediaItemId);
return;
}
view.setState(OverlayView.STATE_OVERLAY);
requestLayout();
invalidate();
}
/**
* An overlay was removed
*
* @param mediaItemId The media item which owns the overlay
* @param overlayId The overlay id
*/
public void removeOverlay(String mediaItemId, String overlayId) {
final OverlayView view = (OverlayView)getOverlayView(mediaItemId);
if (view == null) {
Log.e(TAG, "removeOverlay: Media item not found: " + mediaItemId);
return;
}
view.setState(OverlayView.STATE_STUB);
requestLayout();
invalidate();
if (mOverlayActionMode != null) {
mOverlayActionMode.finish();
mOverlayActionMode = null;
}
}
/**
* Update the overlay attributes
*
* @param mediaItemId The media item id
* @param overlayId The overlay id
* @param userAttributes The overlay attributes
*/
public void updateOverlayAttributes(String mediaItemId, String overlayId,
Bundle userAttributes) {
final MovieMediaItem mediaItem = mProject.getMediaItem(mediaItemId);
if (mediaItem == null) {
Log.e(TAG, "updateOverlayAttributes: Media item not found: " + mediaItemId);
return;
}
final View overlayView = getOverlayView(mediaItemId);
if (overlayView == null) {
Log.e(TAG, "updateOverlayAttributes: Overlay not found: " + overlayId);
return;
}
overlayView.invalidate();
}
/**
* Refresh the view
*/
public void refresh() {
requestLayout();
invalidate();
}
/**
* Invalidate the CAB
*/
public void invalidateCAB() {
if (mOverlayActionMode != null) {
mOverlayActionMode.invalidate();
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final long totalDurationMs = mProject.computeDuration();
final int viewWidth = getWidth() - (2 * mHalfParentWidth);
final int leftViewWidth = (Integer)((View)getParent().getParent()).getTag(
R.id.left_view_width);
long mediaItemStartTimeMs = 0;
int left = 0;
final int childrenCount = getChildCount();
for (int i = 0; i < childrenCount; i++) {
final View view = getChildAt(i);
final MovieMediaItem mediaItem = (MovieMediaItem)view.getTag();
if (mediaItem != null) { // Media item
final MovieOverlay overlay = mediaItem.getOverlay();
final int right;
if (overlay != null) {
// Note that this logic matches the one used in ApiService
// when handling the OP_MEDIA_ITEM_SET_BOUNDARIES command
if (overlay.getAppStartTime() <= mediaItem.getAppBoundaryBeginTime()) {
left = leftViewWidth + (int)((mediaItemStartTimeMs * viewWidth) /
totalDurationMs);
final long durationMs = Math.min(overlay.getAppDuration(),
mediaItem.getAppTimelineDuration());
right = leftViewWidth + (int)(((mediaItemStartTimeMs + durationMs) *
viewWidth) / totalDurationMs);
} else if (overlay.getAppStartTime() + overlay.getAppDuration() >
mediaItem.getAppBoundaryEndTime()) {
final long startTimeMs = Math.max(mediaItem.getAppBoundaryBeginTime(),
mediaItem.getAppBoundaryEndTime() - overlay.getAppDuration());
left = leftViewWidth + (int)(((mediaItemStartTimeMs + startTimeMs -
mediaItem.getAppBoundaryBeginTime()) * viewWidth) /
totalDurationMs);
final long durationMs = mediaItem.getAppBoundaryEndTime() - startTimeMs;
right = leftViewWidth + (int)(((mediaItemStartTimeMs + startTimeMs -
mediaItem.getAppBoundaryBeginTime() +
durationMs) * viewWidth) / totalDurationMs);
} else {
left = leftViewWidth + (int)(((mediaItemStartTimeMs +
overlay.getAppStartTime() - mediaItem.getAppBoundaryBeginTime()) *
viewWidth) / totalDurationMs);
right = leftViewWidth + (int)(((mediaItemStartTimeMs
+ overlay.getAppStartTime() - mediaItem.getAppBoundaryBeginTime() +
overlay.getAppDuration()) * viewWidth) / totalDurationMs);
}
} else {
left = leftViewWidth + (int)((mediaItemStartTimeMs * viewWidth) /
totalDurationMs);
right = leftViewWidth + (int)(((mediaItemStartTimeMs
+ mediaItem.getAppTimelineDuration()) * viewWidth) / totalDurationMs);
}
view.layout(left, 0, right, b - t);
mediaItemStartTimeMs += mediaItem.getAppTimelineDuration();
if (mediaItem.getEndTransition() != null) {
mediaItemStartTimeMs -= mediaItem.getEndTransition().getAppDuration();
}
left = right;
} else if (view == mLeftHandle) {
if (mResizingView != null) {
view.layout(mResizingView.getLeft() - mHandleWidth,
mResizingView.getPaddingTop(),
mResizingView.getLeft(), b - t - mResizingView.getPaddingBottom());
}
} else if (view == mRightHandle) {
if (mResizingView != null) {
view.layout(mResizingView.getRight(), mResizingView.getPaddingTop(),
mResizingView.getRight() + mHandleWidth,
b - t - mResizingView.getPaddingBottom());
}
} else if (i == 0) { // Begin view
view.layout(left, 0, left + leftViewWidth, b - t);
left += leftViewWidth;
} else { // End view
view.layout(getWidth() - mHalfParentWidth - (mHalfParentWidth - leftViewWidth), 0,
getWidth(), b - t);
}
}
mMoveLayoutPending = false;
}
/**
* Create a new dialog
*
* @param id The dialog id
* @param bundle The dialog bundle
* @return The dialog
*/
public Dialog onCreateDialog(int id, final Bundle bundle) {
// If the project is not yet loaded do nothing.
if (mProject == null) {
return null;
}
switch (id) {
case VideoEditorActivity.DIALOG_REMOVE_OVERLAY_ID: {
final MovieMediaItem mediaItem = mProject.getMediaItem(
bundle.getString(PARAM_DIALOG_MEDIA_ITEM_ID));
if (mediaItem == null) {
return null;
}
final Activity activity = (Activity) getContext();
return AlertDialogs.createAlert(activity, FileUtils.getSimpleName(
mediaItem.getFilename()), 0,
activity.getString(R.string.editor_remove_overlay_question),
activity.getString(R.string.yes),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (mOverlayActionMode != null) {
mOverlayActionMode.finish();
mOverlayActionMode = null;
}
activity.removeDialog(VideoEditorActivity.DIALOG_REMOVE_OVERLAY_ID);
ApiService.removeOverlay(activity, mProject.getPath(), mediaItem.getId(),
mediaItem.getOverlay().getId());
}
}, activity.getString(R.string.no), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
activity.removeDialog(VideoEditorActivity.DIALOG_REMOVE_OVERLAY_ID);
}
}, new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
activity.removeDialog(VideoEditorActivity.DIALOG_REMOVE_OVERLAY_ID);
}
}, true);
}
default: {
return null;
}
}
}
/**
* Find the overlay view with the specified id
*
* @param mediaItemId The media item id
* @return The overlay view
*/
private View getOverlayView(String mediaItemId) {
final int childrenCount = getChildCount();
for (int i = 0; i < childrenCount; i++) {
final View childView = getChildAt(i);
final MovieMediaItem mediaItem = (MovieMediaItem)childView.getTag();
if (mediaItem != null && mediaItemId.equals(mediaItem.getId())) {
return childView;
}
}
return null;
}
/**
* Find the media item view index with the specified id
*
* @param mediaItemId The media item id
* @return The media item view index
*/
private int getMediaItemViewIndex(String mediaItemId) {
final int childrenCount = getChildCount();
for (int i = 0; i < childrenCount; i++) {
final View childView = getChildAt(i);
final Object tag = childView.getTag();
if (tag != null && tag instanceof MovieMediaItem) {
final MovieMediaItem mediaItem = (MovieMediaItem)tag;
if (mediaItemId.equals(mediaItem.getId())) {
return i;
}
}
}
return -1;
}
/**
* Remove all overlay views (leave the beginning and end views)
*/
private void removeViews() {
int index = 0;
while (index < getChildCount()) {
final MovieMediaItem mediaItem = (MovieMediaItem)getChildAt(index).getTag();
if (mediaItem != null) {
removeViewAt(index);
} else {
index++;
}
}
requestLayout();
}
@Override
public void setSelected(boolean selected) {
if (selected == false) {
// Close the contextual action bar
if (mOverlayActionMode != null) {
mOverlayActionMode.finish();
mOverlayActionMode = null;
}
mLeftHandle.setVisibility(View.GONE);
mLeftHandle.setListener(null);
mRightHandle.setVisibility(View.GONE);
mRightHandle.setListener(null);
mResizingView = null;
}
final int childrenCount = getChildCount();
for (int i = 0; i < childrenCount; i++) {
final View childView = getChildAt(i);
childView.setSelected(false);
}
}
/**
* Select a view and unselect any view that is selected.
*
* @param view The view to select
* @param selected true if selected
*/
private void selectView(final View selectedView, boolean selected) {
// Check if the selection has changed
if (selectedView.isSelected() == selected) {
return;
}
if (selected == false) {
// Select the new view
selectedView.setSelected(selected);
mResizingView = null;
mLeftHandle.setVisibility(View.GONE);
mLeftHandle.setListener(null);
mRightHandle.setVisibility(View.GONE);
mRightHandle.setListener(null);
return;
}
// Unselect all other views
unselectAllViews();
// Select the new view
selectedView.setSelected(selected);
final Object tag = selectedView.getTag();
final MovieMediaItem mediaItem = (MovieMediaItem)tag;
if (mOverlayActionMode == null) {
startActionMode(new OverlayActionModeCallback(mediaItem));
}
final MovieOverlay overlay = mediaItem.getOverlay();
final View overlayView = getOverlayView(mediaItem.getId());
mResizingView = overlayView;
mRightHandle.setVisibility(View.VISIBLE);
mRightHandle.bringToFront();
mRightHandle.setLimitReached(overlay.getAppDuration() <=
MediaItemUtils.getMinimumMediaItemDuration(mediaItem),
overlay.getAppStartTime() + overlay.getAppDuration() >=
mediaItem.getAppBoundaryEndTime());
mRightHandle.setListener(new HandleView.MoveListener() {
private MovieMediaItem mMediaItem;
private int mMovePosition;
private long mMinimumDurationMs;
@Override
public void onMoveBegin(HandleView view) {
mMediaItem = mediaItem;
mMinimumDurationMs = MediaItemUtils.getMinimumMediaItemDuration(mediaItem);
}
@Override
public boolean onMove(HandleView view, int left, int delta) {
if (mMoveLayoutPending) {
return false;
}
final int position = left + delta;
// Compute what will become the width of the view
final int newWidth = position - overlayView.getLeft();
// Compute the new duration
long newDurationMs = (newWidth * mProject.computeDuration()) /
(getWidth() - (2 * mHalfParentWidth));
if (newDurationMs < mMinimumDurationMs) {
newDurationMs = mMinimumDurationMs;
} else if (overlay.getAppStartTime() + newDurationMs >
mMediaItem.getAppBoundaryEndTime()) {
newDurationMs = mMediaItem.getAppBoundaryEndTime() - overlay.getAppStartTime();
}
mRightHandle.setLimitReached(overlay.getAppDuration() <= mMinimumDurationMs,
overlay.getAppStartTime() + overlay.getAppDuration() >=
mMediaItem.getAppBoundaryEndTime());
overlay.setAppDuration(newDurationMs);
mMovePosition = position;
mMoveLayoutPending = true;
requestLayout();
return true;
}
@Override
public void onMoveEnd(final HandleView view, final int left, final int delta) {
final int position = left + delta;
if (mMoveLayoutPending || (position != mMovePosition)) {
mHandler.post(new Runnable() {
@Override
public void run() {
if (mMoveLayoutPending) {
mHandler.post(this);
} else if (position != mMovePosition) {
if (onMove(view, left, delta)) {
mHandler.post(this);
} else {
scaleDone();
}
} else {
scaleDone();
}
}
});
} else {
scaleDone();
}
}
/**
* Scale is done
*/
public void scaleDone() {
ApiService.setOverlayDuration(getContext(), mProject.getPath(),
mMediaItem.getId(), overlay.getId(), overlay.getAppDuration());
}
});
}
/**
* Unselect all views
*/
private void unselectAllViews() {
((RelativeLayout)getParent()).setSelected(false);
}
}