/* This file is part of Subsonic. Subsonic is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Subsonic is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Subsonic. If not, see . Copyright 2009 (C) Sindre Mehus */ package github.daneren2005.subdroid.util; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.ProgressBar; import github.daneren2005.subdroid.R; /** * @author Sindre Mehus * @version $Id$ */ public class HorizontalSlider extends ProgressBar { private final Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.slider_knob); private boolean slidingEnabled; private OnSliderChangeListener listener; private static final int PADDING = 2; private boolean sliding; private int sliderPosition; private int startPosition; public interface OnSliderChangeListener { void onSliderChanged(View view, int position, boolean inProgress); } public HorizontalSlider(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public HorizontalSlider(Context context, AttributeSet attrs) { super(context, attrs, android.R.attr.progressBarStyleHorizontal); } public HorizontalSlider(Context context) { super(context); } public void setSlidingEnabled(boolean slidingEnabled) { if (this.slidingEnabled != slidingEnabled) { this.slidingEnabled = slidingEnabled; invalidate(); } } public boolean isSlidingEnabled() { return slidingEnabled; } public void setOnSliderChangeListener(OnSliderChangeListener listener) { this.listener = listener; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int max = getMax(); if (!slidingEnabled || max == 0) { return; } int paddingLeft = getPaddingLeft(); int paddingRight = getPaddingRight(); int paddingTop = getPaddingTop(); int paddingBottom = getPaddingBottom(); int w = getWidth() - paddingLeft - paddingRight; int h = getHeight() - paddingTop - paddingBottom; int position = sliding ? sliderPosition : getProgress(); int bitmapWidth = bitmap.getWidth(); int bitmapHeight = bitmap.getWidth(); float x = paddingLeft + w * ((float) position / max) - bitmapWidth / 2.0F; x = Math.max(x, paddingLeft); x = Math.min(x, paddingLeft + w - bitmapWidth); float y = paddingTop + h / 2.0F - bitmapHeight / 2.0F; canvas.drawBitmap(bitmap, x, y, null); } @Override public boolean onTouchEvent(MotionEvent event) { if (!slidingEnabled) { return false; } int action = event.getAction(); if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) { if (action == MotionEvent.ACTION_DOWN) { sliding = true; startPosition = getProgress(); } float x = event.getX() - PADDING; float width = getWidth() - 2 * PADDING; sliderPosition = Math.round((float) getMax() * (x / width)); sliderPosition = Math.max(sliderPosition, 0); setProgress(Math.min(startPosition, sliderPosition)); setSecondaryProgress(Math.max(startPosition, sliderPosition)); if (listener != null) { listener.onSliderChanged(this, sliderPosition, true); } } else if (action == MotionEvent.ACTION_UP) { sliding = false; setProgress(sliderPosition); setSecondaryProgress(0); if (listener != null) { listener.onSliderChanged(this, sliderPosition, false); } } return true; } }