package com.beardedhen.androidbootstrap;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.ImageView;
import com.beardedhen.androidbootstrap.api.attributes.BootstrapBrand;
import com.beardedhen.androidbootstrap.api.defaults.DefaultBootstrapSize;
import com.beardedhen.androidbootstrap.api.view.BootstrapBrandView;
import com.beardedhen.androidbootstrap.api.view.BootstrapSizeView;
import com.beardedhen.androidbootstrap.api.view.BorderView;
import com.beardedhen.androidbootstrap.utils.ColorUtils;
import com.beardedhen.androidbootstrap.utils.DimenUtils;
import java.io.Serializable;
import static android.widget.ImageView.ScaleType.CENTER_CROP;
/**
* Parent class of Circle and Square Thumbnails - contains boilerplate code required to get
* BootstrapBrand and borders working via getters/setters. Also overrides ImageView so that only
* CENTER_CROP is allowed, and a callback is fired whenever the image source changes.
*/
abstract class BootstrapBaseThumbnail extends ImageView implements BootstrapBrandView,
BorderView, BootstrapSizeView {
private static final String TAG = "com.beardedhen.androidbootstrap.BootstrapBaseThumbnail";
protected BootstrapBrand bootstrapBrand;
protected boolean hasBorder;
protected float baselineBorderWidth;
protected float baselineOuterBorderWidth;
protected float bootstrapSize;
protected Bitmap sourceBitmap;
protected final Paint placeholderPaint = new Paint();
protected final Paint borderPaint = new Paint();
protected final Paint imagePaint = new Paint();
public BootstrapBaseThumbnail(Context context) {
super(context);
initialise(null);
}
public BootstrapBaseThumbnail(Context context, AttributeSet attrs) {
super(context, attrs);
initialise(attrs);
}
public BootstrapBaseThumbnail(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialise(attrs);
}
protected void initialise(AttributeSet attrs) {
this.baselineOuterBorderWidth = DimenUtils.pixelsFromDpResource(getContext(), R.dimen.bthumbnail_outer_stroke);
this.baselineBorderWidth = DimenUtils.pixelsFromDpResource(getContext(), R.dimen.bthumbnail_default_border);
setupPaints();
updateImageState();
}
@Override public Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
bundle.putParcelable(TAG, super.onSaveInstanceState());
bundle.putSerializable(BootstrapBrandView.KEY, bootstrapBrand);
bundle.putBoolean(BorderView.KEY_DISPLAYED, hasBorder);
bundle.putFloat(BootstrapSizeView.KEY, bootstrapSize);
return bundle;
}
@Override public void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
this.hasBorder = bundle.getBoolean(BorderView.KEY_DISPLAYED);
this.bootstrapSize = bundle.getFloat(BootstrapSizeView.KEY);
Serializable brand = bundle.getSerializable(BootstrapBrandView.KEY);
if (brand instanceof BootstrapBrand) {
this.bootstrapBrand = (BootstrapBrand) brand;
}
state = bundle.getParcelable(TAG);
}
super.onRestoreInstanceState(state);
updateImageState();
}
private void setupPaints() {
int strokeColor = bootstrapBrand.defaultEdge(getContext());
int placeholderColor = ColorUtils.resolveColor(R.color.bootstrap_gray_light, getContext());
borderPaint.setColor(strokeColor);
borderPaint.setAntiAlias(true);
borderPaint.setStrokeWidth(baselineBorderWidth);
borderPaint.setStyle(Paint.Style.STROKE);
imagePaint.setAntiAlias(true);
placeholderPaint.setColor(placeholderColor);
placeholderPaint.setAntiAlias(true);
placeholderPaint.setStyle(Paint.Style.FILL);
}
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
updateImageState();
}
@Override public void setScaleType(ScaleType scaleType) {
if (scaleType != CENTER_CROP) {
throw new IllegalArgumentException("Only CenterCrop is currently supported by this view");
}
else {
super.setScaleType(scaleType);
}
}
@Override public ScaleType getScaleType() {
return CENTER_CROP;
}
/**
* @return the original Bitmap source that will be drawn as a circular image
*/
@Nullable private Bitmap getBitmapForView() {
Drawable drawable = getDrawable();
if (drawable == null) {
return null;
}
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
else {
int w = drawable.getIntrinsicWidth();
int h = drawable.getIntrinsicHeight();
Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawable.draw(new Canvas(bm));
return bm;
}
}
/*
* Image setter overrides
*/
@Override public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
this.sourceBitmap = bm;
updateImageState();
}
@Override public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
this.sourceBitmap = getBitmapForView();
updateImageState();
}
@Override public void setImageResource(int resId) {
super.setImageResource(resId);
this.sourceBitmap = getBitmapForView();
updateImageState();
}
@Override public void setImageURI(Uri uri) {
super.setImageURI(uri);
this.sourceBitmap = getBitmapForView();
updateImageState();
}
/**
* Called when the ImageView should alter its source bitmap, then invalidate itself.
*/
protected abstract void updateImageState();
/*
* Getters/Setters
*/
@Override public void setBootstrapBrand(@NonNull BootstrapBrand bootstrapBrand) {
this.bootstrapBrand = bootstrapBrand;
updateImageState();
}
@NonNull @Override public BootstrapBrand getBootstrapBrand() {
return bootstrapBrand;
}
@TargetApi(16) @Override public void setBorderDisplayed(boolean displayed) {
this.hasBorder = displayed;
updateImageState();
}
@Override public boolean isBorderDisplayed() {
return hasBorder;
}
@Override public float getBootstrapSize() {
return bootstrapSize;
}
@Override public void setBootstrapSize(float bootstrapSize) {
this.bootstrapSize = bootstrapSize;
updateImageState();
}
@Override public void setBootstrapSize(DefaultBootstrapSize bootstrapSize) {
setBootstrapSize(bootstrapSize.scaleFactor());
}
}