1209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang/* 2209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang * Copyright (C) 2011 The Android Open Source Project 3209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang * 4209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang * Licensed under the Apache License, Version 2.0 (the "License"); 5209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang * you may not use this file except in compliance with the License. 6209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang * You may obtain a copy of the License at 7209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang * 8209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang * http://www.apache.org/licenses/LICENSE-2.0 9209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang * 10209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang * Unless required by applicable law or agreed to in writing, software 11209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang * distributed under the License is distributed on an "AS IS" BASIS, 12209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang * See the License for the specific language governing permissions and 14209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang * limitations under the License. 15209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang */ 16209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 17209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Changpackage com.android.gallery3d.app; 18209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 19209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Changimport android.content.Context; 20209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Changimport android.graphics.Bitmap; 21209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Changimport android.graphics.BitmapFactory; 22209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Changimport android.graphics.Canvas; 23209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Changimport android.graphics.Paint; 24209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Changimport android.graphics.Rect; 25209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Changimport android.util.DisplayMetrics; 26209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Changimport android.view.MotionEvent; 27209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Changimport android.view.View; 28209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 292b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.R; 302b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.common.Utils; 312b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Lin 32209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang/** 333f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * The time bar view, which includes the current and total time, the progress 343f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * bar, and the scrubber. 35209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang */ 36209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Changpublic class TimeBar extends View { 37209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 383f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public interface Listener { 393f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu void onScrubbingStart(); 40209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 413f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu void onScrubbingMove(int time); 42209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 433f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu void onScrubbingEnd(int time, int start, int end); 443f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 45209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 463f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // Padding around the scrubber to increase its touch target 473f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private static final int SCRUBBER_PADDING_IN_DP = 10; 48209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 493f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // The total padding, top plus bottom 503f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private static final int V_PADDING_IN_DP = 30; 51209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 523f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private static final int TEXT_SIZE_IN_DP = 14; 53209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 543f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected final Listener mListener; 55209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 563f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // the bars we use for displaying the progress 573f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected final Rect mProgressBar; 583f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected final Rect mPlayedBar; 59209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 609f59a5fa0302f80cd5bd540e864de091fb5703dfTeng-Hui Zhu protected final Paint mProgressPaint; 619f59a5fa0302f80cd5bd540e864de091fb5703dfTeng-Hui Zhu protected final Paint mPlayedPaint; 629f59a5fa0302f80cd5bd540e864de091fb5703dfTeng-Hui Zhu protected final Paint mTimeTextPaint; 63209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 643f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected final Bitmap mScrubber; 653f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected int mScrubberPadding; // adds some touch tolerance around the 663f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // scrubber 67209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 683f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected int mScrubberLeft; 693f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected int mScrubberTop; 703f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected int mScrubberCorrection; 713f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected boolean mScrubbing; 723f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected boolean mShowTimes; 733f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected boolean mShowScrubber; 74209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 753f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected int mTotalTime; 763f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected int mCurrentTime; 77209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 783f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected final Rect mTimeBounds; 79209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 803f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected int mVPaddingInPx; 81209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 823f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public TimeBar(Context context, Listener listener) { 833f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu super(context); 843f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mListener = Utils.checkNotNull(listener); 85209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 863f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mShowTimes = true; 873f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mShowScrubber = true; 88209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 893f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mProgressBar = new Rect(); 903f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mPlayedBar = new Rect(); 91209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 923f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mProgressPaint = new Paint(); 933f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mProgressPaint.setColor(0xFF808080); 943f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mPlayedPaint = new Paint(); 953f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mPlayedPaint.setColor(0xFFFFFFFF); 96209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 973f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu DisplayMetrics metrics = context.getResources().getDisplayMetrics(); 983f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu float textSizeInPx = metrics.density * TEXT_SIZE_IN_DP; 993f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTimeTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 1003f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTimeTextPaint.setColor(0xFFCECECE); 1013f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTimeTextPaint.setTextSize(textSizeInPx); 1023f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTimeTextPaint.setTextAlign(Paint.Align.CENTER); 103209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 1043f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTimeBounds = new Rect(); 1053f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTimeTextPaint.getTextBounds("0:00:00", 0, 7, mTimeBounds); 106209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 1073f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mScrubber = BitmapFactory.decodeResource(getResources(), R.drawable.scrubber_knob); 1083f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mScrubberPadding = (int) (metrics.density * SCRUBBER_PADDING_IN_DP); 109209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 1103f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVPaddingInPx = (int) (metrics.density * V_PADDING_IN_DP); 111209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang } 112209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 1133f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private void update() { 1143f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mPlayedBar.set(mProgressBar); 1153f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1163f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (mTotalTime > 0) { 1173f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mPlayedBar.right = 1183f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mPlayedBar.left + (int) ((mProgressBar.width() * (long) mCurrentTime) / mTotalTime); 1193f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } else { 1203f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mPlayedBar.right = mProgressBar.left; 1213f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1223f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1233f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (!mScrubbing) { 1243f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mScrubberLeft = mPlayedBar.right - mScrubber.getWidth() / 2; 1253f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1263f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu invalidate(); 127209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang } 1283f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1293f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu /** 1303f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * @return the preferred height of this view, including invisible padding 1313f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu */ 1323f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public int getPreferredHeight() { 1333f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu return mTimeBounds.height() + mVPaddingInPx + mScrubberPadding; 134209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang } 1353f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1363f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu /** 1373f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * @return the height of the time bar, excluding invisible padding 1383f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu */ 1393f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public int getBarHeight() { 1403f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu return mTimeBounds.height() + mVPaddingInPx; 141209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang } 1423f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1433f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void setTime(int currentTime, int totalTime, 1443f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int trimStartTime, int trimEndTime) { 1453f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (mCurrentTime == currentTime && mTotalTime == totalTime) { 1463f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu return; 1473f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1483f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mCurrentTime = currentTime; 1493f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTotalTime = totalTime; 1503f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu update(); 151209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang } 152209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 1533f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private boolean inScrubber(float x, float y) { 1543f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int scrubberRight = mScrubberLeft + mScrubber.getWidth(); 1553f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int scrubberBottom = mScrubberTop + mScrubber.getHeight(); 1563f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu return mScrubberLeft - mScrubberPadding < x && x < scrubberRight + mScrubberPadding 1573f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu && mScrubberTop - mScrubberPadding < y && y < scrubberBottom + mScrubberPadding; 1583f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 159209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 1609f59a5fa0302f80cd5bd540e864de091fb5703dfTeng-Hui Zhu private void clampScrubber() { 1613f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int half = mScrubber.getWidth() / 2; 1623f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int max = mProgressBar.right - half; 1633f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int min = mProgressBar.left - half; 1643f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mScrubberLeft = Math.min(max, Math.max(min, mScrubberLeft)); 1653f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 166209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 1679f59a5fa0302f80cd5bd540e864de091fb5703dfTeng-Hui Zhu private int getScrubberTime() { 1683f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu return (int) ((long) (mScrubberLeft + mScrubber.getWidth() / 2 - mProgressBar.left) 1693f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * mTotalTime / mProgressBar.width()); 170209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang } 1713f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1723f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 1733f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected void onLayout(boolean changed, int l, int t, int r, int b) { 1743f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int w = r - l; 1753f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int h = b - t; 1763f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (!mShowTimes && !mShowScrubber) { 1773f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mProgressBar.set(0, 0, w, h); 1783f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } else { 1793f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int margin = mScrubber.getWidth() / 3; 1803f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (mShowTimes) { 1813f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu margin += mTimeBounds.width(); 1823f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1833f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int progressY = (h + mScrubberPadding) / 2; 1843f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mScrubberTop = progressY - mScrubber.getHeight() / 2 + 1; 1853f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mProgressBar.set( 1863f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu getPaddingLeft() + margin, progressY, 1873f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu w - getPaddingRight() - margin, progressY + 4); 1883f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1893f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu update(); 190209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang } 1913f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1923f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 1933f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected void onDraw(Canvas canvas) { 1943f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // draw progress bars 1953f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu canvas.drawRect(mProgressBar, mProgressPaint); 1963f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu canvas.drawRect(mPlayedBar, mPlayedPaint); 1973f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1983f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // draw scrubber and timers 1993f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (mShowScrubber) { 2003f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu canvas.drawBitmap(mScrubber, mScrubberLeft, mScrubberTop, null); 201bcca048557ff3637b7d1cce2893cfc095111ebddOwen Lin } 2023f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (mShowTimes) { 2033f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu canvas.drawText( 2043f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu stringForTime(mCurrentTime), 2053f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTimeBounds.width() / 2 + getPaddingLeft(), 2063f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTimeBounds.height() + mVPaddingInPx / 2 + mScrubberPadding + 1, 2073f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTimeTextPaint); 2083f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu canvas.drawText( 2093f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu stringForTime(mTotalTime), 2103f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu getWidth() - getPaddingRight() - mTimeBounds.width() / 2, 2113f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTimeBounds.height() + mVPaddingInPx / 2 + mScrubberPadding + 1, 2123f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTimeTextPaint); 213bcca048557ff3637b7d1cce2893cfc095111ebddOwen Lin } 2143f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2153f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2163f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 2173f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public boolean onTouchEvent(MotionEvent event) { 2183f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (mShowScrubber) { 2193f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int x = (int) event.getX(); 2203f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int y = (int) event.getY(); 2213f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2223f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu switch (event.getAction()) { 2233f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu case MotionEvent.ACTION_DOWN: { 2243f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mScrubberCorrection = inScrubber(x, y) 2253f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu ? x - mScrubberLeft 2263f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu : mScrubber.getWidth() / 2; 2273f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mScrubbing = true; 2283f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mListener.onScrubbingStart(); 2293f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2303f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // fall-through 2313f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu case MotionEvent.ACTION_MOVE: { 2323f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mScrubberLeft = x - mScrubberCorrection; 2333f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu clampScrubber(); 2343f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mCurrentTime = getScrubberTime(); 2353f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mListener.onScrubbingMove(mCurrentTime); 2363f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu invalidate(); 2373f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu return true; 2383f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2393f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu case MotionEvent.ACTION_CANCEL: 2403f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu case MotionEvent.ACTION_UP: { 2413f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mListener.onScrubbingEnd(getScrubberTime(), 0, 0); 2423f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mScrubbing = false; 2433f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu return true; 2443f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2453f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 246bcca048557ff3637b7d1cce2893cfc095111ebddOwen Lin } 2473f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu return false; 248209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang } 2493f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2503f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu protected String stringForTime(long millis) { 2513f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int totalSeconds = (int) millis / 1000; 2523f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int seconds = totalSeconds % 60; 2533f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int minutes = (totalSeconds / 60) % 60; 2543f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int hours = totalSeconds / 3600; 2553f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (hours > 0) { 2563f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu return String.format("%d:%02d:%02d", hours, minutes, seconds).toString(); 2573f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } else { 2583f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu return String.format("%02d:%02d", minutes, seconds).toString(); 2593f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 260209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang } 261209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang 262e8b4b34cb77b179f397641e2f4572e4aa6be1943ztenghui public void setSeekable(boolean canSeek) { 263e8b4b34cb77b179f397641e2f4572e4aa6be1943ztenghui mShowScrubber = canSeek; 264e8b4b34cb77b179f397641e2f4572e4aa6be1943ztenghui } 265e8b4b34cb77b179f397641e2f4572e4aa6be1943ztenghui 266209a9163d4e8cee0bfe162ae598ef40e6051479cChih-Chung Chang} 267