diff options
Diffstat (limited to 'src/com/android/gallery3d/app/TrimTimeBar.java')
-rw-r--r-- | src/com/android/gallery3d/app/TrimTimeBar.java | 339 |
1 files changed, 339 insertions, 0 deletions
diff --git a/src/com/android/gallery3d/app/TrimTimeBar.java b/src/com/android/gallery3d/app/TrimTimeBar.java new file mode 100644 index 000000000..f8dbc749e --- /dev/null +++ b/src/com/android/gallery3d/app/TrimTimeBar.java @@ -0,0 +1,339 @@ +/* + * Copyright (C) 2012 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.gallery3d.app; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.view.MotionEvent; + +import com.android.gallery3d.R; + +/** + * The trim time bar view, which includes the current and total time, the progress + * bar, and the scrubbers for current time, start and end time for trimming. + */ +public class TrimTimeBar extends TimeBar { + + public static final int SCRUBBER_NONE = 0; + public static final int SCRUBBER_START = 1; + public static final int SCRUBBER_CURRENT = 2; + public static final int SCRUBBER_END = 3; + + private int mPressedThumb = SCRUBBER_NONE; + + // On touch event, the setting order is Scrubber Position -> Time -> + // PlayedBar. At the setTimes(), activity can update the Time directly, then + // PlayedBar will be updated too. + private int mTrimStartScrubberLeft; + private int mTrimEndScrubberLeft; + + private int mTrimStartScrubberTop; + private int mTrimEndScrubberTop; + + private int mTrimStartTime; + private int mTrimEndTime; + + private final Bitmap mTrimStartScrubber; + private final Bitmap mTrimEndScrubber; + public TrimTimeBar(Context context, Listener listener) { + super(context, listener); + + mTrimStartTime = 0; + mTrimEndTime = 0; + mTrimStartScrubberLeft = 0; + mTrimEndScrubberLeft = 0; + mTrimStartScrubberTop = 0; + mTrimEndScrubberTop = 0; + + mTrimStartScrubber = BitmapFactory.decodeResource(getResources(), + R.drawable.text_select_handle_left); + mTrimEndScrubber = BitmapFactory.decodeResource(getResources(), + R.drawable.text_select_handle_right); + // Increase the size of this trimTimeBar, but minimize the scrubber + // touch padding since we have 3 scrubbers now. + mScrubberPadding = 0; + mVPaddingInPx = mVPaddingInPx * 3 / 2; + } + + private int getBarPosFromTime(int time) { + return mProgressBar.left + + (int) ((mProgressBar.width() * (long) time) / mTotalTime); + } + + private int trimStartScrubberTipOffset() { + return mTrimStartScrubber.getWidth() * 3 / 4; + } + + private int trimEndScrubberTipOffset() { + return mTrimEndScrubber.getWidth() / 4; + } + + // Based on all the time info (current, total, trimStart, trimEnd), we + // decide the playedBar size. + private void updatePlayedBarAndScrubberFromTime() { + // According to the Time, update the Played Bar + mPlayedBar.set(mProgressBar); + if (mTotalTime > 0) { + // set playedBar according to the trim time. + mPlayedBar.left = getBarPosFromTime(mTrimStartTime); + mPlayedBar.right = getBarPosFromTime(mCurrentTime); + if (!mScrubbing) { + mScrubberLeft = mPlayedBar.right - mScrubber.getWidth() / 2; + mTrimStartScrubberLeft = mPlayedBar.left - trimStartScrubberTipOffset(); + mTrimEndScrubberLeft = getBarPosFromTime(mTrimEndTime) + - trimEndScrubberTipOffset(); + } + } else { + // If the video is not prepared, just show the scrubber at the end + // of progressBar + mPlayedBar.right = mProgressBar.left; + mScrubberLeft = mProgressBar.left - mScrubber.getWidth() / 2; + mTrimStartScrubberLeft = mProgressBar.left - trimStartScrubberTipOffset(); + mTrimEndScrubberLeft = mProgressBar.right - trimEndScrubberTipOffset(); + } + } + + private void initTrimTimeIfNeeded() { + if (mTotalTime > 0 && mTrimEndTime == 0) { + mTrimEndTime = mTotalTime; + } + } + + private void update() { + initTrimTimeIfNeeded(); + updatePlayedBarAndScrubberFromTime(); + invalidate(); + } + + @Override + public void setTime(int currentTime, int totalTime, + int trimStartTime, int trimEndTime) { + if (mCurrentTime == currentTime && mTotalTime == totalTime + && mTrimStartTime == trimStartTime && mTrimEndTime == trimEndTime) { + return; + } + mCurrentTime = currentTime; + mTotalTime = totalTime; + mTrimStartTime = trimStartTime; + mTrimEndTime = trimEndTime; + update(); + } + + private int whichScrubber(float x, float y) { + if (inScrubber(x, y, mTrimStartScrubberLeft, mTrimStartScrubberTop, mTrimStartScrubber)) { + return SCRUBBER_START; + } else if (inScrubber(x, y, mTrimEndScrubberLeft, mTrimEndScrubberTop, mTrimEndScrubber)) { + return SCRUBBER_END; + } else if (inScrubber(x, y, mScrubberLeft, mScrubberTop, mScrubber)) { + return SCRUBBER_CURRENT; + } + return SCRUBBER_NONE; + } + + private boolean inScrubber(float x, float y, int startX, int startY, Bitmap scrubber) { + int scrubberRight = startX + scrubber.getWidth(); + int scrubberBottom = startY + scrubber.getHeight(); + return startX < x && x < scrubberRight && startY < y && y < scrubberBottom; + } + + private int clampScrubber(int scrubberLeft, int offset, int lowerBound, int upperBound) { + int max = upperBound - offset; + int min = lowerBound - offset; + return Math.min(max, Math.max(min, scrubberLeft)); + } + + private int getScrubberTime(int scrubberLeft, int offset) { + return (int) ((long) (scrubberLeft + offset - mProgressBar.left) + * mTotalTime / mProgressBar.width()); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + int w = r - l; + int h = b - t; + if (!mShowTimes && !mShowScrubber) { + mProgressBar.set(0, 0, w, h); + } else { + int margin = mScrubber.getWidth() / 3; + if (mShowTimes) { + margin += mTimeBounds.width(); + } + int progressY = h / 4; + int scrubberY = progressY - mScrubber.getHeight() / 2 + 1; + mScrubberTop = scrubberY; + mTrimStartScrubberTop = progressY; + mTrimEndScrubberTop = progressY; + mProgressBar.set( + getPaddingLeft() + margin, progressY, + w - getPaddingRight() - margin, progressY + 4); + } + update(); + } + + @Override + protected void onDraw(Canvas canvas) { + // draw progress bars + canvas.drawRect(mProgressBar, mProgressPaint); + canvas.drawRect(mPlayedBar, mPlayedPaint); + + if (mShowTimes) { + canvas.drawText( + stringForTime(mCurrentTime), + mTimeBounds.width() / 2 + getPaddingLeft(), + mTimeBounds.height() / 2 + mTrimStartScrubberTop, + mTimeTextPaint); + canvas.drawText( + stringForTime(mTotalTime), + getWidth() - getPaddingRight() - mTimeBounds.width() / 2, + mTimeBounds.height() / 2 + mTrimStartScrubberTop, + mTimeTextPaint); + } + + // draw extra scrubbers + if (mShowScrubber) { + canvas.drawBitmap(mScrubber, mScrubberLeft, mScrubberTop, null); + canvas.drawBitmap(mTrimStartScrubber, mTrimStartScrubberLeft, + mTrimStartScrubberTop, null); + canvas.drawBitmap(mTrimEndScrubber, mTrimEndScrubberLeft, + mTrimEndScrubberTop, null); + } + } + + private void updateTimeFromPos() { + mCurrentTime = getScrubberTime(mScrubberLeft, mScrubber.getWidth() / 2); + mTrimStartTime = getScrubberTime(mTrimStartScrubberLeft, trimStartScrubberTipOffset()); + mTrimEndTime = getScrubberTime(mTrimEndScrubberLeft, trimEndScrubberTipOffset()); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (mShowScrubber) { + int x = (int) event.getX(); + int y = (int) event.getY(); + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + mPressedThumb = whichScrubber(x, y); + switch (mPressedThumb) { + case SCRUBBER_NONE: + break; + case SCRUBBER_CURRENT: + mScrubbing = true; + mScrubberCorrection = x - mScrubberLeft; + break; + case SCRUBBER_START: + mScrubbing = true; + mScrubberCorrection = x - mTrimStartScrubberLeft; + break; + case SCRUBBER_END: + mScrubbing = true; + mScrubberCorrection = x - mTrimEndScrubberLeft; + break; + } + if (mScrubbing == true) { + mListener.onScrubbingStart(); + return true; + } + break; + case MotionEvent.ACTION_MOVE: + if (mScrubbing) { + int seekToTime = -1; + int lowerBound = mTrimStartScrubberLeft + trimStartScrubberTipOffset(); + int upperBound = mTrimEndScrubberLeft + trimEndScrubberTipOffset(); + switch (mPressedThumb) { + case SCRUBBER_CURRENT: + mScrubberLeft = x - mScrubberCorrection; + mScrubberLeft = + clampScrubber(mScrubberLeft, + mScrubber.getWidth() / 2, + lowerBound, upperBound); + seekToTime = getScrubberTime(mScrubberLeft, + mScrubber.getWidth() / 2); + break; + case SCRUBBER_START: + mTrimStartScrubberLeft = x - mScrubberCorrection; + // Limit start <= end + if (mTrimStartScrubberLeft > mTrimEndScrubberLeft) { + mTrimStartScrubberLeft = mTrimEndScrubberLeft; + } + lowerBound = mProgressBar.left; + mTrimStartScrubberLeft = + clampScrubber(mTrimStartScrubberLeft, + trimStartScrubberTipOffset(), + lowerBound, upperBound); + seekToTime = getScrubberTime(mTrimStartScrubberLeft, + trimStartScrubberTipOffset()); + break; + case SCRUBBER_END: + mTrimEndScrubberLeft = x - mScrubberCorrection; + upperBound = mProgressBar.right; + mTrimEndScrubberLeft = + clampScrubber(mTrimEndScrubberLeft, + trimEndScrubberTipOffset(), + lowerBound, upperBound); + seekToTime = getScrubberTime(mTrimEndScrubberLeft, + trimEndScrubberTipOffset()); + break; + } + updateTimeFromPos(); + updatePlayedBarAndScrubberFromTime(); + if (seekToTime != -1) { + mListener.onScrubbingMove(seekToTime); + } + invalidate(); + return true; + } + break; + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + if (mScrubbing) { + int seekToTime = 0; + switch (mPressedThumb) { + case SCRUBBER_CURRENT: + seekToTime = getScrubberTime(mScrubberLeft, + mScrubber.getWidth() / 2); + break; + case SCRUBBER_START: + seekToTime = getScrubberTime(mTrimStartScrubberLeft, + trimStartScrubberTipOffset()); + mScrubberLeft = mTrimStartScrubberLeft + + trimStartScrubberTipOffset() - mScrubber.getWidth() / 2; + break; + case SCRUBBER_END: + seekToTime = getScrubberTime(mTrimEndScrubberLeft, + trimEndScrubberTipOffset()); + mScrubberLeft = mTrimEndScrubberLeft + + trimEndScrubberTipOffset() - mScrubber.getWidth() / 2; + break; + } + updateTimeFromPos(); + mListener.onScrubbingEnd(seekToTime, + getScrubberTime(mTrimStartScrubberLeft, + trimStartScrubberTipOffset()), + getScrubberTime(mTrimEndScrubberLeft, trimEndScrubberTipOffset())); + mScrubbing = false; + mPressedThumb = SCRUBBER_NONE; + return true; + } + break; + } + } + return false; + } +} |