package info.guardianproject.securereaderinterface.widgets;
import info.guardianproject.securereaderinterface.models.ViewPagerIndicator;
import info.guardianproject.securereaderinterface.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
public class PageIndicatorView extends View implements ViewPagerIndicator
{
private int mGravity;
private int mNumDots; // Total number of dots
private int mCurrentDot; // Current dot
private boolean mHideIfOnlyOne = true;
private Drawable mDrawable;
private int mWselected;
private int mHselected;
private int mWunselected;
private int mHunselected;
public PageIndicatorView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
}
public PageIndicatorView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public PageIndicatorView(Context context) {
super(context);
init(null);
}
private void init(AttributeSet attrs)
{
mGravity = Gravity.CENTER;
if (attrs != null)
{
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.PageIndicatorView);
mGravity = a.getInt(R.styleable.PageIndicatorView_android_gravity, Gravity.CENTER);
mNumDots = a.getInt(R.styleable.PageIndicatorView_dot_total, 3);
mCurrentDot = a.getInt(R.styleable.PageIndicatorView_dot_current, 1);
mHideIfOnlyOne = a.getBoolean(R.styleable.PageIndicatorView_hide_if_only_one, true);
mDrawable = a.getDrawable(R.styleable.PageIndicatorView_android_drawable);
a.recycle();
}
if (mDrawable != null)
{
mDrawable.setState(new int[] { android.R.attr.state_selected });
mWselected = mDrawable.getCurrent().getIntrinsicWidth();
mHselected = mDrawable.getCurrent().getIntrinsicHeight();
mDrawable.setState(new int[] { 0 });
mWunselected = mDrawable.getCurrent().getIntrinsicWidth();
mHunselected = mDrawable.getCurrent().getIntrinsicHeight();
}
}
/*
* Calculate the number of dots we can fit in the screen space we are given.
*/
private int getMaxNumberOfDots()
{
int w = this.getWidth();
if (mWunselected == -1 || mWselected == -1)
return 0;
// Start with current "dot"
int n = 0;
if (w >= mWselected)
{
n++;
w -= mWselected;
}
if (w >= mWunselected)
{
n += w / mWunselected;
}
return n;
}
private int getNumDotsWidth(int numDots)
{
if (mWunselected == -1 || mWselected == -1)
return 0;
// Start with current "dot"
int n = 0;
if (numDots >= 1)
{
numDots -= 1;
n += mWselected;
}
n += numDots * mWunselected;
return n;
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
if (mNumDots <= 1 && mHideIfOnlyOne)
{
return;
}
int sc = canvas.save();
int numDotsToDraw = mNumDots;
int currentDot = mCurrentDot;
// If all dots don't fit, show only the remaining pages (see design
// document)
//
int dotsPerPage = getMaxNumberOfDots();
if (dotsPerPage < mNumDots)
{
// Get the current "page" for the current dot
int page = (int) ((float) mCurrentDot / (dotsPerPage - 1));
currentDot = (int) ((float) mCurrentDot % (dotsPerPage - 1));
numDotsToDraw = Math.min(dotsPerPage, 1 + mNumDots - (page * dotsPerPage));
}
int xPos = 0;
int widthOfDots = this.getNumDotsWidth(numDotsToDraw);
if (mGravity == Gravity.RIGHT)
{
xPos = getWidth() - widthOfDots;
}
else if (mGravity == Gravity.CENTER_HORIZONTAL)
{
xPos = (getWidth() - widthOfDots) / 2;
}
// Do the draw
for (int i = 0; i < numDotsToDraw; i++)
{
if (i == currentDot)
{
mDrawable.setState(new int[] { android.R.attr.state_selected });
mDrawable.getCurrent().setBounds(xPos, getHeight() / 2 - mHselected / 2, xPos + mWselected, getHeight() / 2 + mHselected / 2);
mDrawable.getCurrent().draw(canvas);
xPos += mWselected;
}
else
{
mDrawable.setState(new int[] { 0 });
mDrawable.getCurrent().setBounds(xPos, getHeight() / 2 - mHunselected / 2, xPos + mWunselected, getHeight() / 2 + mHunselected / 2);
mDrawable.getCurrent().draw(canvas);
xPos += mWunselected;
}
}
canvas.restoreToCount(sc);
}
@Override
public void onTotalChanged(int total)
{
if (total != mNumDots)
{
mNumDots = total;
invalidate();
}
}
@Override
public void onCurrentChanged(int current)
{
if (current != mCurrentDot)
{
mCurrentDot = current;
invalidate();
}
}
}