package b4a.circularprogressbar.objects;
import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.BA.ActivityObject;
import anywheresoftware.b4a.BA.Author;
import anywheresoftware.b4a.BA.DependsOn;
import anywheresoftware.b4a.BA.Permissions;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.BA.Version;
//import com.lylc.widget.circularprogressbar.example;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.ProgressBar;
@Version(1.0f)
@ShortName("B4ACircularProgressBar")
@ActivityObject
//@Permissions(values={"android.permission.INTERNET"})
@Author("Theera Soontornwongsakorn")
//@DependsOn(values = { "CircularProgressBar" })
public class CircularProgressBarWrapper extends ProgressBar{
private static final String TAG = "CircularProgressBar";
private static final int STROKE_WIDTH = 20;
private String mTitle = "";
private String mSubTitle = "";
private int mStrokeWidth = STROKE_WIDTH;
private final RectF mCircleBounds = new RectF();
private final Paint mProgressColorPaint = new Paint();
private final Paint mBackgroundColorPaint = new Paint();
private final Paint mTitlePaint = new Paint();
private final Paint mSubtitlePaint = new Paint();
private boolean mHasShadow = true;
private int mShadowColor = Color.BLACK;
public interface ProgressAnimationListener{
public void onAnimationStart();
public void onAnimationFinish();
public void onAnimationProgress(int progress);
}
public CircularProgressBar(BA ba) {
super(ba);
init(null, 0);
}
public CircularProgressBar(BA ba, AttributeSet attrs) {
super(ba, attrs);
init(attrs, 0);
}
public CircularProgressBar(BA ba, AttributeSet attrs, int defStyle) {
super(ba, attrs, defStyle);
init(attrs, defStyle);
}
public void init(AttributeSet attrs, int style){
//so that shadow shows up properly for lines and arcs
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
TypedArray a = getContext().obtainStyledAttributes(attrs,
R.styleable.CircularProgressBar, style, 0);
String color;
Resources res = getResources();
this.mHasShadow = a.getBoolean(R.styleable.CircularProgressBar_hasShadow, true);
color = a.getString(R.styleable.CircularProgressBar_progressColor);
if(color==null)
mProgressColorPaint.setColor(res.getColor(R.color.circular_progress_default_progress));
else
mProgressColorPaint.setColor(Color.parseColor(color));
color = a.getString(R.styleable.CircularProgressBar_backgroundColor);
if(color==null)
mBackgroundColorPaint.setColor(res.getColor(R.color.circular_progress_default_background));
else
mBackgroundColorPaint.setColor(Color.parseColor(color));
color = a.getString(R.styleable.CircularProgressBar_titleColor);
if(color==null)
mTitlePaint.setColor(res.getColor(R.color.circular_progress_default_title));
else
mTitlePaint.setColor(Color.parseColor(color));
color = a.getString(R.styleable.CircularProgressBar_subtitleColor);
if(color==null)
mSubtitlePaint.setColor(res.getColor(R.color.circular_progress_default_subtitle));
else
mSubtitlePaint.setColor(Color.parseColor(color));
String t = a.getString(R.styleable.CircularProgressBar_title);
if(t!=null)
mTitle = t;
t = a.getString(R.styleable.CircularProgressBar_subtitle);
if(t!=null)
mSubTitle = t;
mStrokeWidth = a.getInt(R.styleable.CircularProgressBar_strokeWidth, STROKE_WIDTH);
a.recycle();
mProgressColorPaint.setAntiAlias(true);
mProgressColorPaint.setStyle(Paint.Style.STROKE);
mProgressColorPaint.setStrokeWidth(mStrokeWidth);
mBackgroundColorPaint.setAntiAlias(true);
mBackgroundColorPaint.setStyle(Paint.Style.STROKE);
mBackgroundColorPaint.setStrokeWidth(mStrokeWidth);
mTitlePaint.setTextSize(60);
mTitlePaint.setStyle(Style.FILL);
mTitlePaint.setAntiAlias(true);
mTitlePaint.setTypeface(Typeface.create("Roboto-Thin", Typeface.NORMAL));
mTitlePaint.setShadowLayer(0.1f, 0, 1, Color.GRAY);
mSubtitlePaint.setTextSize(20);
mSubtitlePaint.setStyle(Style.FILL);
mSubtitlePaint.setAntiAlias(true);
mSubtitlePaint.setTypeface(Typeface.create("Roboto-Thin", Typeface.BOLD));
// mSubtitlePaint.setShadowLayer(0.1f, 0, 1, Color.GRAY);
}
@Override
protected synchronized void onDraw(Canvas canvas) {
canvas.drawArc(mCircleBounds, 0, 360 , false, mBackgroundColorPaint);
int prog = getProgress();
float scale = getMax() > 0 ? (float)prog/getMax() *360: 0;
if(mHasShadow)
mProgressColorPaint.setShadowLayer( 3, 0, 1, mShadowColor);
canvas.drawArc(mCircleBounds, 270, scale , false, mProgressColorPaint);
if(!TextUtils.isEmpty(mTitle)){
int xPos = (int)(getMeasuredWidth()/2 - mTitlePaint.measureText(mTitle) / 2);
int yPos = (int) (getMeasuredHeight()/2);
float titleHeight = Math.abs(mTitlePaint.descent() + mTitlePaint.ascent());
if(TextUtils.isEmpty(mSubTitle)){
yPos += titleHeight/2;
}
canvas.drawText(mTitle, xPos, yPos, mTitlePaint);
yPos += titleHeight;
xPos = (int)(getMeasuredWidth()/2 - mSubtitlePaint.measureText(mSubTitle) / 2);
canvas.drawText(mSubTitle, xPos, yPos, mSubtitlePaint);
}
super.onDraw(canvas);
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
final int height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
final int width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int min = Math.min(width, height);
setMeasuredDimension(min+2*STROKE_WIDTH, min+2*STROKE_WIDTH);
mCircleBounds.set(STROKE_WIDTH, STROKE_WIDTH, min+STROKE_WIDTH, min+STROKE_WIDTH);
}
@Override
public synchronized void setProgress(int progress) {
super.setProgress(progress);
// the setProgress super will not change the details of the progress bar
// anymore so we need to force an update to redraw the progress bar
invalidate();
}
public void animateProgressTo(final int start, final int end, final ProgressAnimationListener listener){
if(start!=0)
setProgress(start);
final ObjectAnimator progressBarAnimator = ObjectAnimator.ofFloat(this, "animateProgress", start, end);
progressBarAnimator.setDuration(1500);
// progressBarAnimator.setInterpolator(new AnticipateOvershootInterpolator(2f, 1.5f));
progressBarAnimator.setInterpolator(new LinearInterpolator());
progressBarAnimator.addListener(new AnimatorListener() {
@Override
public void onAnimationCancel(final Animator animation) {
}
@Override
public void onAnimationEnd(final Animator animation) {
CircularProgressBar.this.setProgress(end);
if(listener!=null)
listener.onAnimationFinish();
}
@Override
public void onAnimationRepeat(final Animator animation) {
}
@Override
public void onAnimationStart(final Animator animation) {
if(listener!=null)
listener.onAnimationStart();
}
});
progressBarAnimator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(final ValueAnimator animation) {
int progress = ((Float) animation.getAnimatedValue()).intValue();
if(progress!=CircularProgressBar.this.getProgress()){
Log.d(TAG, progress + "");
CircularProgressBar.this.setProgress(progress);
if(listener!=null)
listener.onAnimationProgress(progress);
}
}
});
progressBarAnimator.start();
}
public synchronized void setTitle(String title){
CircularProgressBarWrapper.mTitle = title;
invalidate();
}
public synchronized void setSubTitle(String subtitle){
CircularProgressBarWrapper.mSubTitle = subtitle;
invalidate();
}
public synchronized void setSubTitleColor(int color){
mSubtitlePaint.setColor(color);
invalidate();
}
public synchronized void setTitleColor(int color){
mTitlePaint.setColor(color);
invalidate();
}
public synchronized void setHasShadow(boolean flag){
CircularProgressBarWrapper.mHasShadow = flag;
invalidate();
}
public synchronized void setShadow(int color){
CircularProgressBarWrapper.mShadowColor = color;
invalidate();
}
public String getTitle(){
return mTitle;
}
public boolean getHasShadow(){
return mHasShadow;
}
}