package me.barrasso.android.volume.ui;
// Android Packages
import android.content.Context;
import android.graphics.Canvas;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ProgressBar;
import android.view.Gravity;
import android.graphics.drawable.ClipDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RectShape;
import android.graphics.Color;
import android.graphics.Rect;
/**
* Originally used to display a MIUI-style battery bar. Now it's
* just a VERY simple {@link android.widget.ProgressBar} that shows
* a solid color and respects right-to-left layouts.
*/
public final class CmBatteryBar extends ProgressBar
{
private static final String SUPERSTATE = "superstate",
COLOR = "color";
/**
* Default color of a {@link CmBatteryBar}, #FF33B5E5.
*/
public static final int DEFAULT_COLOR = Color.argb(0xFF, 0x33, 0xB5, 0xE5);
// Color of the bar. #FF33B5E5 default
private int color = DEFAULT_COLOR;
public CmBatteryBar(Context context) {
this(context, null);
init();
}
public CmBatteryBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
init();
}
public CmBatteryBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
protected void init() { }
private ShapeDrawable mSecondaryProgress;
private ShapeDrawable mProgress;
private ShapeDrawable mBackground;
/**
* Creates a {@link Drawable} of a solid color.
*/
private LayerDrawable getDrawableForColor(int color)
{
if (mBackground == null)
mBackground = new ShapeDrawable(new RectShape());
if (mProgress == null)
mProgress = new ShapeDrawable(new RectShape());
if (mSecondaryProgress == null)
mSecondaryProgress = new ShapeDrawable(new RectShape());
// Set the colors based on whether or not we are "inverse".
mProgress.getPaint().setColor(color);
mBackground.getPaint().setColor(Color.TRANSPARENT);
mSecondaryProgress.getPaint().setColor(Color.TRANSPARENT);
final ClipDrawable mProgClip = new ClipDrawable(
mProgress, Gravity.LEFT, ClipDrawable.HORIZONTAL);
final ClipDrawable mSecClip = new ClipDrawable(
mSecondaryProgress, Gravity.LEFT, ClipDrawable.HORIZONTAL);
final LayerDrawable mLayers = new LayerDrawable(
new Drawable[] { mBackground, mSecClip, mProgClip });
// Do funky layered crap.
mLayers.setDrawableByLayerId(android.R.id.background, mBackground);
mLayers.setDrawableByLayerId(android.R.id.secondaryProgress, mSecClip);
mLayers.setDrawableByLayerId(android.R.id.progress, mProgClip);
mLayers.setId(0, android.R.id.background);
mLayers.setId(1, android.R.id.secondaryProgress);
mLayers.setId(2, android.R.id.progress);
return mLayers;
}
public final boolean isInverse() { return getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; }
/**
* Sets the color of the battery bar.
*/
public final void setColor(int mColor) {
this.color = mColor;
setProgressDrawable(getDrawableForColor(mColor), mColor);
invalidate();
}
@Override
public void setProgress(int progress) {
super.setProgress(progress);
invalidate();
}
/**
* Updates the {@link ShapeDrawable} which displays the
* color of the bar across the screen.
*/
public void setProgressDrawable(Drawable mDrawable, int mNewColor)
{
if (mDrawable instanceof LayerDrawable &&
getProgressDrawable() instanceof LayerDrawable)
{
final LayerDrawable mDraw = (LayerDrawable) getProgressDrawable();
final ClipDrawable mShape = (ClipDrawable)
mDraw.findDrawableByLayerId(android.R.id.progress);
// Make sure we've got everything.
if (mShape != null && mProgress != null &&
mProgress.getPaint() != null)
{
mProgress.getPaint().setColor(mNewColor);
final Rect mBounds = mDraw.getBounds();
super.setProgressDrawable(mDraw);
getProgressDrawable().setBounds(mBounds);
return;
}
}
super.setProgressDrawable(mDrawable);
}
/**
* @return The color of the battery bar.
*/
public final int getColor() {
return this.color;
}
// Custom onDraw to handle inverse stuff!
@Override
protected synchronized void onDraw(Canvas canvas) {
if (getVisibility() != View.VISIBLE || getProgress() <= 0) return;
if (!isInverse()) {
super.onDraw(canvas);
} else {
int count = canvas.save();
// Set the canvas to the middle of the screen.
// The calculation is the center (px) minus half
// of the barHeight of the actual visible bar.
// if (mCentered)
// canvas.translate((getWidth() / 2.0f) - ((getProgress()
// / (getMax() * 2.0f)) * getWidth()), 0);
// Now we change the matrix.
// We need to rotate around the center of our text.
// Otherwise it rotates around the origin, and that's bad.
if (isInverse())
canvas.rotate(180, (getWidth() / 2.0f), (getHeight() / 2.0f));
// Draw the progress bar with the matrix applied.
super.onDraw(canvas);
// Restore the old matrix.
canvas.restoreToCount(count);
}
}
// ====================
// Saved State
// ====================
@Override
public Parcelable onSaveInstanceState() {
final Bundle state = new Bundle();
state.putParcelable(SUPERSTATE, super.onSaveInstanceState());
state.putInt(COLOR, color);
return(state);
}
@Override
public void onRestoreInstanceState(Parcelable ss) {
final Bundle state = (Bundle) ss;
super.onRestoreInstanceState(state.getParcelable(SUPERSTATE));
int color = state.getInt(COLOR);
setColor(color);
}
}