154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project/* 254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * 454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * you may not use this file except in compliance with the License. 654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * You may obtain a copy of the License at 754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * 854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * 1054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * See the License for the specific language governing permissions and 1454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * limitations under the License. 1554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 1654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 1754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectpackage android.widget; 1854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 1954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.content.Context; 2054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.content.res.TypedArray; 2154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.Canvas; 2254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.Rect; 2354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.drawable.Drawable; 24c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanvimport android.os.Bundle; 2554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.util.AttributeSet; 26b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Projectimport android.view.KeyEvent; 2754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.view.MotionEvent; 281029866a12e04e9db52485e2ec0353e764d15549Adam Powellimport android.view.ViewConfiguration; 298a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent; 308a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo; 3154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 3254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectpublic abstract class AbsSeekBar extends ProgressBar { 3354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project private Drawable mThumb; 3454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project private int mThumbOffset; 3554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 3654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project /** 3754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * On touch, this offset plus the scaled value from the position of the 3854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * touch will form the progress value. Usually 0. 3954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 4054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project float mTouchProgressOffset; 4154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 4254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project /** 4354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Whether this is user seekable. 4454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 4554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project boolean mIsUserSeekable = true; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * On key presses (right or left), the amount to increment/decrement the 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * progress. 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mKeyProgressIncrement = 1; 5254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 5354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project private static final int NO_ALPHA = 0xFF; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mDisabledAlpha; 5554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 561029866a12e04e9db52485e2ec0353e764d15549Adam Powell private int mScaledTouchSlop; 571029866a12e04e9db52485e2ec0353e764d15549Adam Powell private float mTouchDownX; 581029866a12e04e9db52485e2ec0353e764d15549Adam Powell private boolean mIsDragging; 591029866a12e04e9db52485e2ec0353e764d15549Adam Powell 6054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public AbsSeekBar(Context context) { 6154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super(context); 6254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 6354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 6454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public AbsSeekBar(Context context, AttributeSet attrs) { 6554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super(context, attrs); 6654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 6754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 6854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public AbsSeekBar(Context context, AttributeSet attrs, int defStyle) { 6954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super(context, attrs, defStyle); 7054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 7154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project TypedArray a = context.obtainStyledAttributes(attrs, 7254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project com.android.internal.R.styleable.SeekBar, defStyle, 0); 7354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Drawable thumb = a.getDrawable(com.android.internal.R.styleable.SeekBar_thumb); 748d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler setThumb(thumb); // will guess mThumbOffset if thumb != null... 758d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler // ...but allow layout to override this 76992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy int thumbOffset = a.getDimensionPixelOffset( 77992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy com.android.internal.R.styleable.SeekBar_thumbOffset, getThumbOffset()); 78992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy setThumbOffset(thumbOffset); 7954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project a.recycle(); 8054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 8154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project a = context.obtainStyledAttributes(attrs, 8254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project com.android.internal.R.styleable.Theme, 0, 0); 8354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mDisabledAlpha = a.getFloat(com.android.internal.R.styleable.Theme_disabledAlpha, 0.5f); 8454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project a.recycle(); 851029866a12e04e9db52485e2ec0353e764d15549Adam Powell 861029866a12e04e9db52485e2ec0353e764d15549Adam Powell mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); 8754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 8854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 8954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project /** 908d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler * Sets the thumb that will be drawn at the end of the progress meter within the SeekBar. 918d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler * <p> 928d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler * If the thumb is a valid drawable (i.e. not null), half its width will be 938d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler * used as the new thumb offset (@see #setThumbOffset(int)). 9454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * 9554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * @param thumb Drawable representing the thumb 9654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 9754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void setThumb(Drawable thumb) { 982e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato boolean needUpdate; 992e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato // This way, calling setThumb again with the same bitmap will result in 1002e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato // it recalcuating mThumbOffset (if for example it the bounds of the 1012e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato // drawable changed) 1022e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato if (mThumb != null && thumb != mThumb) { 1032e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato mThumb.setCallback(null); 1042e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato needUpdate = true; 1052e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato } else { 1062e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato needUpdate = false; 1072e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato } 10854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (thumb != null) { 10954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project thumb.setCallback(this); 1100af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio if (canResolveLayoutDirection()) { 111e56ffdc7b31b0937628609cc3bbaa15879023569Fabrice Di Meglio thumb.setLayoutDirection(getLayoutDirection()); 1120af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio } 1138d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler 1148d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler // Assuming the thumb drawable is symmetric, set the thumb offset 1158d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler // such that the thumb will hang halfway off either edge of the 1168d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler // progress bar. 117992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy mThumbOffset = thumb.getIntrinsicWidth() / 2; 1182e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato 1192e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato // If we're updating get the new states 1202e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato if (needUpdate && 1212e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato (thumb.getIntrinsicWidth() != mThumb.getIntrinsicWidth() 1222e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato || thumb.getIntrinsicHeight() != mThumb.getIntrinsicHeight())) { 1232e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato requestLayout(); 1242e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato } 12554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 12654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mThumb = thumb; 12754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project invalidate(); 1282e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato if (needUpdate) { 1292e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato updateThumbPos(getWidth(), getHeight()); 1300283a5573c0a8b239f88147fe4ecf1b379e2f0a4Adam Powell if (thumb != null && thumb.isStateful()) { 1312e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato // Note that if the states are different this won't work. 1322e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato // For now, let's consider that an app bug. 1332e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato int[] state = getDrawableState(); 1342e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato thumb.setState(state); 1352e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato } 1362e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato } 13754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 13854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 13954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project /** 1403004cc50f22e724efb791aa80e9d6c566d2ddb5dAdam Powell * Return the drawable used to represent the scroll thumb - the component that 1413004cc50f22e724efb791aa80e9d6c566d2ddb5dAdam Powell * the user can drag back and forth indicating the current value by its position. 1423004cc50f22e724efb791aa80e9d6c566d2ddb5dAdam Powell * 1433004cc50f22e724efb791aa80e9d6c566d2ddb5dAdam Powell * @return The current thumb drawable 1443004cc50f22e724efb791aa80e9d6c566d2ddb5dAdam Powell */ 1453004cc50f22e724efb791aa80e9d6c566d2ddb5dAdam Powell public Drawable getThumb() { 1463004cc50f22e724efb791aa80e9d6c566d2ddb5dAdam Powell return mThumb; 1473004cc50f22e724efb791aa80e9d6c566d2ddb5dAdam Powell } 1483004cc50f22e724efb791aa80e9d6c566d2ddb5dAdam Powell 1493004cc50f22e724efb791aa80e9d6c566d2ddb5dAdam Powell /** 15054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * @see #setThumbOffset(int) 15154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 15254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public int getThumbOffset() { 15354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return mThumbOffset; 15454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 15554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 15654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project /** 15754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Sets the thumb offset that allows the thumb to extend out of the range of 15854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * the track. 15954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * 16054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * @param thumbOffset The offset amount in pixels. 16154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 16254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public void setThumbOffset(int thumbOffset) { 16354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mThumbOffset = thumbOffset; 16454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project invalidate(); 16554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 16654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the amount of progress changed via the arrow keys. 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param increment The amount to increment or decrement when the user 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * presses the arrow keys. 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setKeyProgressIncrement(int increment) { 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mKeyProgressIncrement = increment < 0 ? -increment : increment; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the amount of progress changed via the arrow keys. 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, this will be a value that is derived from the max progress. 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The amount to increment or decrement when the user presses the 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * arrow keys. This will be positive. 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getKeyProgressIncrement() { 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mKeyProgressIncrement; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized void setMax(int max) { 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.setMax(max); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mKeyProgressIncrement == 0) || (getMax() / mKeyProgressIncrement > 20)) { 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // It will take the user too long to change this via keys, change it 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to something more reasonable 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setKeyProgressIncrement(Math.max(1, Math.round((float) getMax() / 20))); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 20154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected boolean verifyDrawable(Drawable who) { 20254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return who == mThumb || super.verifyDrawable(who); 20354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 20454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 20554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 206e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn public void jumpDrawablesToCurrentState() { 207e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn super.jumpDrawablesToCurrentState(); 208e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn if (mThumb != null) mThumb.jumpToCurrentState(); 209e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn } 210e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn 211e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn @Override 21254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected void drawableStateChanged() { 21354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super.drawableStateChanged(); 21454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 21554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Drawable progressDrawable = getProgressDrawable(); 21654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (progressDrawable != null) { 21754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project progressDrawable.setAlpha(isEnabled() ? NO_ALPHA : (int) (NO_ALPHA * mDisabledAlpha)); 21854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 219b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project 220b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project if (mThumb != null && mThumb.isStateful()) { 221b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project int[] state = getDrawableState(); 222b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project mThumb.setState(state); 223b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project } 22454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 22554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 22654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 2276518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov void onProgressRefresh(float scale, boolean fromUser) { 2286518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov super.onProgressRefresh(scale, fromUser); 22954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Drawable thumb = mThumb; 23054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (thumb != null) { 231105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE); 23254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project /* 23354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Since we draw translated, the drawable's bounds that it signals 23454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * for invalidation won't be the actual bounds we want invalidated, 23554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * so just invalidate this whole view. 23654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 23754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project invalidate(); 23854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 23954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 24054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 24154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 24254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 24354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected void onSizeChanged(int w, int h, int oldw, int oldh) { 244f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio super.onSizeChanged(w, h, oldw, oldh); 2452e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato updateThumbPos(w, h); 2462e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato } 2472e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato 2482e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato private void updateThumbPos(int w, int h) { 24954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Drawable d = getCurrentDrawable(); 25054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Drawable thumb = mThumb; 25154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int thumbHeight = thumb == null ? 0 : thumb.getIntrinsicHeight(); 25254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // The max height does not incorporate padding, whereas the height 25354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // parameter does 25454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int trackHeight = Math.min(mMaxHeight, h - mPaddingTop - mPaddingBottom); 25554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 25654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int max = getMax(); 25754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project float scale = max > 0 ? (float) getProgress() / (float) max : 0; 25854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 25954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (thumbHeight > trackHeight) { 26054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (thumb != null) { 261105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project setThumbPos(w, thumb, scale, 0); 26254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 26354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int gapForCenteringTrack = (thumbHeight - trackHeight) / 2; 26454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (d != null) { 26554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // Canvas will be translated by the padding, so 0,0 is where we start drawing 26654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project d.setBounds(0, gapForCenteringTrack, 26754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project w - mPaddingRight - mPaddingLeft, h - mPaddingBottom - gapForCenteringTrack 26854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project - mPaddingTop); 26954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 27054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } else { 27154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (d != null) { 27254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // Canvas will be translated by the padding, so 0,0 is where we start drawing 27354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project d.setBounds(0, 0, w - mPaddingRight - mPaddingLeft, h - mPaddingBottom 27454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project - mPaddingTop); 27554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 27654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int gap = (trackHeight - thumbHeight) / 2; 27754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (thumb != null) { 278105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project setThumbPos(w, thumb, scale, gap); 27954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 28054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 28154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 28254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 28354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project /** 28454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * @param gap If set to {@link Integer#MIN_VALUE}, this will be ignored and 28554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 286105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private void setThumbPos(int w, Drawable thumb, float scale, int gap) { 28754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int available = w - mPaddingLeft - mPaddingRight; 28854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int thumbWidth = thumb.getIntrinsicWidth(); 28954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int thumbHeight = thumb.getIntrinsicHeight(); 29054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project available -= thumbWidth; 29154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 29254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // The extra space for the thumb to move on the track 29354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project available += mThumbOffset * 2; 29454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 29554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int thumbPos = (int) (scale * available); 29654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 29754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int topBound, bottomBound; 29854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (gap == Integer.MIN_VALUE) { 29954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Rect oldBounds = thumb.getBounds(); 30054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project topBound = oldBounds.top; 30154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project bottomBound = oldBounds.bottom; 30254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } else { 30354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project topBound = gap; 30454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project bottomBound = gap + thumbHeight; 30554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 30654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 30754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // Canvas will be translated, so 0,0 is where we start drawing 30806849e8f5368831086b0c33f9037a015fb00e864Fabrice Di Meglio final int left = isLayoutRtl() ? available - thumbPos : thumbPos; 30906849e8f5368831086b0c33f9037a015fb00e864Fabrice Di Meglio thumb.setBounds(left, topBound, left + thumbWidth, bottomBound); 31054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 3110af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio 3124457e85a7090ad51726d50a4daf981d917cceeddFabrice Di Meglio /** 3134457e85a7090ad51726d50a4daf981d917cceeddFabrice Di Meglio * @hide 3144457e85a7090ad51726d50a4daf981d917cceeddFabrice Di Meglio */ 3150af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio @Override 3160af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio public void onResolveDrawables(int layoutDirection) { 3170af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio super.onResolveDrawables(layoutDirection); 3180af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio 3190af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio if (mThumb != null) { 3200af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio mThumb.setLayoutDirection(layoutDirection); 3210af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio } 3220af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio } 3230af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio 32454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 32554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected synchronized void onDraw(Canvas canvas) { 32654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project super.onDraw(canvas); 32754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (mThumb != null) { 32854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project canvas.save(); 32954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // Translate the padding. For the x, we need to allow the thumb to 33054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project // draw in its extra space 33154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project canvas.translate(mPaddingLeft - mThumbOffset, mPaddingTop); 33254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project mThumb.draw(canvas); 33354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project canvas.restore(); 33454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 33554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 33654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 33754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 33854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 33954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project Drawable d = getCurrentDrawable(); 34054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 34154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int thumbHeight = mThumb == null ? 0 : mThumb.getIntrinsicHeight(); 34254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int dw = 0; 34354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int dh = 0; 34454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (d != null) { 34554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project dw = Math.max(mMinWidth, Math.min(mMaxWidth, d.getIntrinsicWidth())); 34654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project dh = Math.max(mMinHeight, Math.min(mMaxHeight, d.getIntrinsicHeight())); 34754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project dh = Math.max(thumbHeight, dh); 34854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 34954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project dw += mPaddingLeft + mPaddingRight; 35054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project dh += mPaddingTop + mPaddingBottom; 35154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 352189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn setMeasuredDimension(resolveSizeAndState(dw, widthMeasureSpec, 0), 353189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn resolveSizeAndState(dh, heightMeasureSpec, 0)); 35454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 35554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 35654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project @Override 35754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project public boolean onTouchEvent(MotionEvent event) { 35854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project if (!mIsUserSeekable || !isEnabled()) { 35954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return false; 36054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 36154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 36254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project switch (event.getAction()) { 36354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project case MotionEvent.ACTION_DOWN: 3641029866a12e04e9db52485e2ec0353e764d15549Adam Powell if (isInScrollingContainer()) { 3651029866a12e04e9db52485e2ec0353e764d15549Adam Powell mTouchDownX = event.getX(); 3661029866a12e04e9db52485e2ec0353e764d15549Adam Powell } else { 3671029866a12e04e9db52485e2ec0353e764d15549Adam Powell setPressed(true); 3682c5b8cc71bc8ac1efa944568c1292929073bbc36Adam Powell if (mThumb != null) { 3692c5b8cc71bc8ac1efa944568c1292929073bbc36Adam Powell invalidate(mThumb.getBounds()); // This may be within the padding region 3702c5b8cc71bc8ac1efa944568c1292929073bbc36Adam Powell } 3711029866a12e04e9db52485e2ec0353e764d15549Adam Powell onStartTrackingTouch(); 3721029866a12e04e9db52485e2ec0353e764d15549Adam Powell trackTouchEvent(event); 3731029866a12e04e9db52485e2ec0353e764d15549Adam Powell attemptClaimDrag(); 3741029866a12e04e9db52485e2ec0353e764d15549Adam Powell } 37554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project break; 37654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 37754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project case MotionEvent.ACTION_MOVE: 3781029866a12e04e9db52485e2ec0353e764d15549Adam Powell if (mIsDragging) { 3791029866a12e04e9db52485e2ec0353e764d15549Adam Powell trackTouchEvent(event); 3801029866a12e04e9db52485e2ec0353e764d15549Adam Powell } else { 3811029866a12e04e9db52485e2ec0353e764d15549Adam Powell final float x = event.getX(); 3821029866a12e04e9db52485e2ec0353e764d15549Adam Powell if (Math.abs(x - mTouchDownX) > mScaledTouchSlop) { 3831029866a12e04e9db52485e2ec0353e764d15549Adam Powell setPressed(true); 3842c5b8cc71bc8ac1efa944568c1292929073bbc36Adam Powell if (mThumb != null) { 3852c5b8cc71bc8ac1efa944568c1292929073bbc36Adam Powell invalidate(mThumb.getBounds()); // This may be within the padding region 3862c5b8cc71bc8ac1efa944568c1292929073bbc36Adam Powell } 3871029866a12e04e9db52485e2ec0353e764d15549Adam Powell onStartTrackingTouch(); 3881029866a12e04e9db52485e2ec0353e764d15549Adam Powell trackTouchEvent(event); 3891029866a12e04e9db52485e2ec0353e764d15549Adam Powell attemptClaimDrag(); 3901029866a12e04e9db52485e2ec0353e764d15549Adam Powell } 3911029866a12e04e9db52485e2ec0353e764d15549Adam Powell } 39254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project break; 39354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 39454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project case MotionEvent.ACTION_UP: 3951029866a12e04e9db52485e2ec0353e764d15549Adam Powell if (mIsDragging) { 3961029866a12e04e9db52485e2ec0353e764d15549Adam Powell trackTouchEvent(event); 3971029866a12e04e9db52485e2ec0353e764d15549Adam Powell onStopTrackingTouch(); 3981029866a12e04e9db52485e2ec0353e764d15549Adam Powell setPressed(false); 3991029866a12e04e9db52485e2ec0353e764d15549Adam Powell } else { 4001029866a12e04e9db52485e2ec0353e764d15549Adam Powell // Touch up when we never crossed the touch slop threshold should 4011029866a12e04e9db52485e2ec0353e764d15549Adam Powell // be interpreted as a tap-seek to that location. 4021029866a12e04e9db52485e2ec0353e764d15549Adam Powell onStartTrackingTouch(); 4031029866a12e04e9db52485e2ec0353e764d15549Adam Powell trackTouchEvent(event); 4041029866a12e04e9db52485e2ec0353e764d15549Adam Powell onStopTrackingTouch(); 4051029866a12e04e9db52485e2ec0353e764d15549Adam Powell } 406eb9fdc21b14368b2f8c71939eb063ddcee8c28a2Daniel Sandler // ProgressBar doesn't know to repaint the thumb drawable 407eb9fdc21b14368b2f8c71939eb063ddcee8c28a2Daniel Sandler // in its inactive state when the touch stops (because the 408eb9fdc21b14368b2f8c71939eb063ddcee8c28a2Daniel Sandler // value has not apparently changed) 409eb9fdc21b14368b2f8c71939eb063ddcee8c28a2Daniel Sandler invalidate(); 41054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project break; 41154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 41254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project case MotionEvent.ACTION_CANCEL: 4131029866a12e04e9db52485e2ec0353e764d15549Adam Powell if (mIsDragging) { 4141029866a12e04e9db52485e2ec0353e764d15549Adam Powell onStopTrackingTouch(); 4151029866a12e04e9db52485e2ec0353e764d15549Adam Powell setPressed(false); 4161029866a12e04e9db52485e2ec0353e764d15549Adam Powell } 417eb9fdc21b14368b2f8c71939eb063ddcee8c28a2Daniel Sandler invalidate(); // see above explanation 41854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project break; 41954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 42054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project return true; 42154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 42254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 42354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project private void trackTouchEvent(MotionEvent event) { 42454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final int width = getWidth(); 42554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project final int available = width - mPaddingLeft - mPaddingRight; 42654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project int x = (int)event.getX(); 42754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project float scale; 42854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project float progress = 0; 4290af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio if (isLayoutRtl()) { 4300af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio if (x > width - mPaddingRight) { 4310af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio scale = 0.0f; 4320af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio } else if (x < mPaddingLeft) { 4330af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio scale = 1.0f; 4340af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio } else { 4350af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio scale = (float)(available - x + mPaddingLeft) / (float)available; 4360af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio progress = mTouchProgressOffset; 4370af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio } 43854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } else { 4390af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio if (x < mPaddingLeft) { 4400af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio scale = 0.0f; 4410af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio } else if (x > width - mPaddingRight) { 4420af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio scale = 1.0f; 4430af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio } else { 4440af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio scale = (float)(x - mPaddingLeft) / (float)available; 4450af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio progress = mTouchProgressOffset; 4460af4b8b0c8b038bca9b4f60eb81f71e186f471ceFabrice Di Meglio } 44754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 44869577ae794751e6ecaca6a580b1b33545bd21082Jean-Baptiste Queru final int max = getMax(); 44954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project progress += scale * max; 45054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 45154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project setProgress((int) progress, true); 45254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 453f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project 454f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project /** 455f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project * Tries to claim the user's drag motion, and requests disallowing any 456f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project * ancestors from stealing events in the drag. 457f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project */ 458f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project private void attemptClaimDrag() { 459f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project if (mParent != null) { 460f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project mParent.requestDisallowInterceptTouchEvent(true); 461f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project } 462f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project } 46354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 46454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project /** 46554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * This is called when the user has started touching this widget. 46654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 46754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project void onStartTrackingTouch() { 4681029866a12e04e9db52485e2ec0353e764d15549Adam Powell mIsDragging = true; 46954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 47054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 47154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project /** 47254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * This is called when the user either releases his touch or the touch is 47354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * canceled. 47454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */ 47554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project void onStopTrackingTouch() { 4761029866a12e04e9db52485e2ec0353e764d15549Adam Powell mIsDragging = false; 47754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project } 47854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project 479105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project /** 480105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project * Called when the user changes the seekbar's progress by using a key event. 481105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project */ 482105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project void onKeyChange() { 483105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 484105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 485b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project @Override 486b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project public boolean onKeyDown(int keyCode, KeyEvent event) { 487992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy if (isEnabled()) { 488992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy int progress = getProgress(); 489992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy switch (keyCode) { 490992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy case KeyEvent.KEYCODE_DPAD_LEFT: 491992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy if (progress <= 0) break; 492992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy setProgress(progress - mKeyProgressIncrement, true); 493992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy onKeyChange(); 494992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy return true; 495992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy 496992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy case KeyEvent.KEYCODE_DPAD_RIGHT: 497992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy if (progress >= getMax()) break; 498992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy setProgress(progress + mKeyProgressIncrement, true); 499992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy onKeyChange(); 500992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy return true; 501992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy } 502b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project } 503b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project 504b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project return super.onKeyDown(keyCode, event); 505b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project } 506b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project 5078a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov @Override 5088a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 5098a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov super.onInitializeAccessibilityEvent(event); 5108a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov event.setClassName(AbsSeekBar.class.getName()); 5118a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov } 5128a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov 5138a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov @Override 5148a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 5158a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov super.onInitializeAccessibilityNodeInfo(info); 5168a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov info.setClassName(AbsSeekBar.class.getName()); 517c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv 518c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv if (isEnabled()) { 519c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv final int progress = getProgress(); 520c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv if (progress > 0) { 521c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); 522c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv } 523c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv if (progress < getMax()) { 524c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); 525c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv } 526c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv } 527c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv } 528c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv 529c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv @Override 530c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv public boolean performAccessibilityAction(int action, Bundle arguments) { 531c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv if (super.performAccessibilityAction(action, arguments)) { 532c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv return true; 533c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv } 534c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv if (!isEnabled()) { 535c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv return false; 536c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv } 537c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv final int progress = getProgress(); 538c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv final int increment = Math.max(1, Math.round((float) getMax() / 5)); 539c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv switch (action) { 540c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: { 541c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv if (progress <= 0) { 542c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv return false; 543c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv } 544c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv setProgress(progress - increment, true); 545c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv onKeyChange(); 546c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv return true; 547c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv } 548c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: { 549c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv if (progress >= getMax()) { 550c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv return false; 551c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv } 552c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv setProgress(progress + increment, true); 553c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv onKeyChange(); 554c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv return true; 555c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv } 556c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv } 557c826b7d8fa330970d1ab29fd3b2790a5bc01e26calanv return false; 5588a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov } 559f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio 560f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio @Override 561f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio public void onRtlPropertiesChanged(int layoutDirection) { 562f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio super.onRtlPropertiesChanged(layoutDirection); 563f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio 564f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio int max = getMax(); 565f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio float scale = max > 0 ? (float) getProgress() / (float) max : 0; 566f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio 567f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio Drawable thumb = mThumb; 568f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio if (thumb != null) { 569f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE); 570f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio /* 571f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio * Since we draw translated, the drawable's bounds that it signals 572f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio * for invalidation won't be the actual bounds we want invalidated, 573f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio * so just invalidate this whole view. 574f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio */ 575f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio invalidate(); 576f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio } 577f37df1b6c23316e3050a399f9218087c4000564aFabrice Di Meglio } 57854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project} 579