--- /dev/null
+package com.moiseum.wolnelektury.view.book.components;
+
+/**
+ * Created by Piotr Ostrowski on 21.11.2017.
+ */
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Typeface;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.moiseum.wolnelektury.R;
+
+import java.util.Locale;
+
+public class ProgressDownloadButton extends View {
+
+ private static final int MAX_PROGRESS_VALUE = 100;
+
+ public enum ProgressDownloadButtonState {
+ STATE_INITIAL {
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+ @Override
+ public boolean isDownloaded() {
+ return false;
+ }
+
+ @Override
+ public boolean isDeletable() {
+ return false;
+ }
+
+ @Override
+ public void draw(Canvas canvas, ProgressDownloadButtonAttributes attributes, int width, int height) {
+ int posY = getPosY(attributes, height);
+ canvas.drawText(attributes.initialText, attributes.paddingStart, posY, attributes.textPaint);
+ int top = (height - attributes.iconBitmap.getHeight()) / 2;
+ canvas.drawBitmap(attributes.iconBitmap, width - attributes.iconBitmap.getWidth() - attributes.paddingEnd, top, attributes
+ .bitmapPaint);
+ }
+ }, STATE_DOWNLOADING {
+ @Override
+ public boolean isEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isDownloaded() {
+ throw new IllegalStateException("This method shall not be called within this state");
+ }
+
+ @Override
+ public boolean isDeletable() {
+ return false;
+ }
+
+ @Override
+ public void draw(Canvas canvas, ProgressDownloadButtonAttributes attributes, int width, int height) {
+ int posY = getPosY(attributes, height);
+ String text = String.format(Locale.getDefault(), "%s: %d%%", attributes.loadingText, attributes.currentProgress);
+
+ // Draw text to overlap.
+ canvas.drawText(text, attributes.paddingStart, posY, attributes.textPaint);
+
+ // Draw icon to overlap.
+ int top = (height - attributes.iconBitmap.getHeight()) / 2;
+ canvas.drawBitmap(attributes.iconBitmap, width - attributes.iconBitmap.getWidth() - attributes.paddingEnd, top, attributes
+ .bitmapPaint);
+
+ // Draw progress
+ int currentProgress = attributes.currentProgress;
+ if (currentProgress >= 0 && currentProgress <= MAX_PROGRESS_VALUE) {
+ attributes.baseRect.right = attributes.baseRect.width() * currentProgress / MAX_PROGRESS_VALUE;
+ canvas.clipRect(attributes.baseRect);
+ }
+
+ // Draw current state.
+ canvas.drawRoundRect(attributes.outerRectF, attributes.cornerRadius, attributes.cornerRadius, attributes.textPaint);
+ canvas.drawText(text, attributes.paddingStart, posY, attributes.invertedPaint);
+ canvas.drawBitmap(attributes.iconBitmap, width - attributes.iconBitmap.getWidth() - attributes.paddingEnd, top, attributes
+ .bitmapInvertedPaint);
+ }
+ }, STATE_READING {
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+ @Override
+ public boolean isDownloaded() {
+ return true;
+ }
+
+ @Override
+ public boolean isDeletable() {
+ return true;
+ }
+
+ @Override
+ public void draw(Canvas canvas, ProgressDownloadButtonAttributes attributes, int width, int height) {
+ int posY = getPosY(attributes, height);
+ int top = (height - attributes.iconBitmap.getHeight()) / 2;
+ String text = String.format(Locale.getDefault(), "%1$s: %2$d/%3$d", attributes.downloadedText, attributes
+ .currentReadPosition, attributes.totalReadCount);
+
+ canvas.drawRoundRect(attributes.outerRectF, attributes.cornerRadius, attributes.cornerRadius, attributes.textPaint);
+ canvas.drawText(text, attributes.paddingStart, posY, attributes.invertedPaint);
+ canvas.drawBitmap(attributes.iconBitmap, width - attributes.iconBitmap.getWidth() - attributes.paddingEnd, top, attributes
+ .bitmapInvertedPaint);
+ }
+ };
+
+ private static int getPosY(ProgressDownloadButtonAttributes attributes, int height) {
+ return (int) ((height / 2) - ((attributes.textPaint.descent() + attributes.textPaint.ascent()) / 2));
+ }
+
+ public abstract boolean isEnabled();
+
+ public abstract boolean isDownloaded();
+
+ public abstract boolean isDeletable();
+
+ public abstract void draw(Canvas canvas, ProgressDownloadButtonAttributes attributes, int width, int height);
+ }
+
+ private static class ProgressDownloadButtonAttributes {
+ private String initialText = "";
+ private String downloadedText = "";
+ private String loadingText;
+
+ private Rect baseRect = new Rect();
+ private RectF outerRectF = new RectF();
+ private RectF innerRectF = new RectF();
+
+ private int currentProgress = 0;
+ private int currentReadPosition;
+ private int totalReadCount;
+
+ private Paint textPaint;
+ private Paint invertedPaint;
+ private Paint bitmapPaint;
+ private Paint bitmapInvertedPaint;
+
+ private Bitmap iconBitmap;
+ private int cornerRadius;
+ private int innerCornerRadius;
+ private int borderSize;
+ private int paddingStart;
+ private int paddingEnd;
+ }
+
+
+ private ProgressDownloadButtonState currentState = ProgressDownloadButtonState.STATE_INITIAL;
+ private ProgressDownloadButtonAttributes attributes;
+
+ public ProgressDownloadButton(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ initComponents(context, attrs, defStyle, 0);
+ }
+
+ public ProgressDownloadButton(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initComponents(context, attrs, 0, 0);
+ }
+
+ public ProgressDownloadButton(Context context) {
+ super(context);
+ }
+
+ // public InvertedTextProgressbar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ // super(context, attrs, defStyleAttr, defStyleRes);
+ // initComponents(context, attrs, defStyleAttr, defStyleRes);
+ // }
+
+ /**
+ * Initializes the text paint. This has a fix size.
+ *
+ * @param attrs The XML attributes to use.
+ */
+ @SuppressLint("ResourceType")
+ private void initComponents(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ attributes = new ProgressDownloadButtonAttributes();
+
+ TypedArray baseAttributes = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.paddingStart, android.R.attr
+ .paddingEnd});
+ TypedArray styledAttributes = context.obtainStyledAttributes(attrs, R.styleable.ProgressDownloadButton, defStyleAttr, defStyleRes);
+
+ attributes.paddingStart = baseAttributes.getDimensionPixelOffset(0, 0);
+ attributes.paddingEnd = baseAttributes.getDimensionPixelOffset(1, 0);
+
+ Paint textPaint = new Paint();
+ textPaint.setColor(styledAttributes.getColor(R.styleable.ProgressDownloadButton_text_color, Color.BLACK));
+ textPaint.setStyle(Paint.Style.FILL);
+ textPaint.setTextSize(styledAttributes.getDimensionPixelSize(R.styleable.ProgressDownloadButton_text_size, context.getResources()
+ .getDimensionPixelSize(R.dimen.download_button_text_size_default)));
+ textPaint.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL));
+ textPaint.setTextAlign(Paint.Align.LEFT); // Text draw is started in the middle
+ textPaint.setLinearText(true);
+ textPaint.setAntiAlias(true);
+
+ // Define the inverted text paint.
+ Paint invertedPaint = new Paint(textPaint);
+ invertedPaint.setColor(styledAttributes.getColor(R.styleable.ProgressDownloadButton_text_inverted_color, Color.WHITE));
+ attributes.textPaint = textPaint;
+ attributes.invertedPaint = invertedPaint;
+
+ // Define paint for drawable
+ Paint bitmapPaint = new Paint();
+ bitmapPaint.setColorFilter(new PorterDuffColorFilter(styledAttributes.getColor(R.styleable.ProgressDownloadButton_text_color,
+ Color.BLACK), PorterDuff.Mode.SRC_ATOP));
+ attributes.bitmapPaint = bitmapPaint;
+
+ // Define paint for inverted drawable
+ Paint bitmapInvertedPaint = new Paint();
+ bitmapInvertedPaint.setColorFilter(new PorterDuffColorFilter(styledAttributes.getColor(R.styleable
+ .ProgressDownloadButton_text_inverted_color, Color.WHITE), PorterDuff.Mode.SRC_ATOP));
+ attributes.bitmapInvertedPaint = bitmapInvertedPaint;
+
+ // Define the text.
+ String initialText = styledAttributes.getString(R.styleable.ProgressDownloadButton_text_initial);
+ if (initialText != null) {
+ initialText = initialText.toUpperCase();
+ attributes.initialText = initialText;
+ }
+ String downloadedText = styledAttributes.getString(R.styleable.ProgressDownloadButton_text_downloaded);
+ if (downloadedText != null) {
+ downloadedText = downloadedText.toUpperCase();
+ attributes.downloadedText = downloadedText;
+ }
+ attributes.loadingText = context.getString(R.string.download_ebook_loading);
+
+ // Load drawable
+ attributes.iconBitmap = BitmapFactory.decodeResource(getResources(), styledAttributes.getResourceId(R.styleable
+ .ProgressDownloadButton_drawable, android.R.drawable.ic_delete));
+
+ attributes.borderSize = styledAttributes.getDimensionPixelSize(R.styleable.ProgressDownloadButton_border_size, context
+ .getResources().getDimensionPixelSize(R.dimen.download_button_border_size_default));
+ attributes.cornerRadius = styledAttributes.getDimensionPixelSize(R.styleable.ProgressDownloadButton_corner_radius, context
+ .getResources().getDimensionPixelSize(R.dimen.download_button_corner_radius_default));
+ attributes.innerCornerRadius = attributes.cornerRadius - attributes.borderSize;
+
+ // Recycle the TypedArray.
+ baseAttributes.recycle();
+ styledAttributes.recycle();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ canvas.getClipBounds(attributes.baseRect);
+ RectF outerRectF = attributes.outerRectF;
+ int borderSize = attributes.borderSize;
+ outerRectF.set(attributes.baseRect);
+ attributes.innerRectF.set(outerRectF.left + borderSize, outerRectF.top + borderSize, outerRectF.right - borderSize, outerRectF
+ .bottom - borderSize);
+
+ // Draw outline
+ canvas.drawRoundRect(outerRectF, attributes.cornerRadius, attributes.cornerRadius, attributes.textPaint);
+ canvas.drawRoundRect(attributes.innerRectF, attributes.innerCornerRadius, attributes.innerCornerRadius, attributes.invertedPaint);
+
+ // Draw current state
+ getState().draw(canvas, attributes, getWidth(), getHeight());
+ }
+
+ public void setState(ProgressDownloadButtonState state) {
+ this.currentState = state;
+ this.setEnabled(state.isEnabled());
+ invalidate();
+ }
+
+ public ProgressDownloadButtonState getState() {
+ return currentState;
+ }
+
+ /**
+ * Sets the text that will overlay.
+ *
+ * @param text The text to draw.
+ */
+ public void setText(String text) {
+ attributes.initialText = text;
+ }
+
+ /**
+ * Gets the current text to draw.
+ *
+ * @return The current text to draw.
+ */
+ public String getText() {
+ return attributes.initialText;
+ }
+
+ public int getCurrentProgress() {
+ return attributes.currentProgress;
+ }
+
+ public void setProgress(int progress) {
+ attributes.currentProgress = progress;
+ invalidate();
+ }
+
+ public void setCurrentReadCount(int position, int count) {
+ attributes.currentReadPosition = position;
+ attributes.totalReadCount = count;
+ invalidate();
+ }
+}
\ No newline at end of file