X-Git-Url: https://git.mdrn.pl/wl-app.git/blobdiff_plain/48b2fe9f7c2dc3d9aeaaa6dbfb27c7da4f3235ff..269195b3729c1bdc22e9053ee4ebca667ea8549d:/Android/app/src/main/java/com/moiseum/wolnelektury/view/book/components/ProgressDownloadButton.java diff --git a/Android/app/src/main/java/com/moiseum/wolnelektury/view/book/components/ProgressDownloadButton.java b/Android/app/src/main/java/com/moiseum/wolnelektury/view/book/components/ProgressDownloadButton.java new file mode 100644 index 0000000..5d177d8 --- /dev/null +++ b/Android/app/src/main/java/com/moiseum/wolnelektury/view/book/components/ProgressDownloadButton.java @@ -0,0 +1,321 @@ +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