aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/app/src/main/java/com/wireguard/android/widget/fab/FloatingActionButton.java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/com/wireguard/android/widget/fab/FloatingActionButton.java')
-rw-r--r--app/src/main/java/com/wireguard/android/widget/fab/FloatingActionButton.java446
1 files changed, 0 insertions, 446 deletions
diff --git a/app/src/main/java/com/wireguard/android/widget/fab/FloatingActionButton.java b/app/src/main/java/com/wireguard/android/widget/fab/FloatingActionButton.java
deleted file mode 100644
index 417ae52d..00000000
--- a/app/src/main/java/com/wireguard/android/widget/fab/FloatingActionButton.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Copyright © 2014 Jerzy Chalupski
- * Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package com.wireguard.android.widget.fab;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.LinearGradient;
-import android.graphics.Paint;
-import android.graphics.Paint.Style;
-import android.graphics.Rect;
-import android.graphics.Shader;
-import android.graphics.Shader.TileMode;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LayerDrawable;
-import android.graphics.drawable.ShapeDrawable;
-import android.graphics.drawable.ShapeDrawable.ShaderFactory;
-import android.graphics.drawable.StateListDrawable;
-import android.graphics.drawable.shapes.OvalShape;
-import android.support.annotation.ColorRes;
-import android.support.annotation.DimenRes;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.IntDef;
-import android.support.annotation.NonNull;
-import android.support.v4.content.ContextCompat;
-import android.support.v7.widget.AppCompatImageButton;
-import android.util.AttributeSet;
-import android.widget.TextView;
-
-import com.wireguard.android.R;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-public class FloatingActionButton extends AppCompatImageButton {
-
- public static final int SIZE_NORMAL = 0;
- public static final int SIZE_MINI = 1;
- int mColorNormal;
- int mColorPressed;
- int mColorDisabled;
- String mTitle;
- boolean mStrokeVisible;
- @DrawableRes
- private int mIcon;
- private Drawable mIconDrawable;
- private int mSize;
-
- private float mCircleSize;
- private float mShadowRadius;
- private float mShadowOffset;
- private int mDrawableSize;
- public FloatingActionButton(final Context context) {
- this(context, null);
- }
-
- public FloatingActionButton(final Context context, final AttributeSet attrs) {
- super(context, attrs);
- init(context, attrs);
- }
-
- public FloatingActionButton(final Context context, final AttributeSet attrs, final int defStyle) {
- super(context, attrs, defStyle);
- init(context, attrs);
- }
-
- public static int getColorFromTheme(final Context context, final int themeResource, @ColorRes final int fallback) {
- final TypedArray a = context.obtainStyledAttributes(new int[]{themeResource});
- try {
- return a.getColor(0, ContextCompat.getColor(context, fallback));
- } finally {
- a.recycle();
- }
- }
-
- void init(final Context context, final AttributeSet attributeSet) {
- final TypedArray attr = context.obtainStyledAttributes(attributeSet,
- R.styleable.FloatingActionButton, 0, 0);
- mColorNormal = attr.getColor(R.styleable.FloatingActionButton_fab_colorNormal,
- getColorFromTheme(context, android.R.attr.colorAccent, android.R.color.holo_blue_bright));
- mColorPressed = attr.getColor(R.styleable.FloatingActionButton_fab_colorPressed,
- darkenOrLightenColor(mColorNormal)); //TODO(msf): use getColorForState on the accent color from theme instead to get darker states
- mColorDisabled = attr.getColor(R.styleable.FloatingActionButton_fab_colorDisabled,
- ContextCompat.getColor(context, android.R.color.darker_gray)); //TODO(msf): load from theme
- mSize = attr.getInt(R.styleable.FloatingActionButton_fab_size, SIZE_NORMAL);
- mIcon = attr.getResourceId(R.styleable.FloatingActionButton_fab_icon, 0);
- mTitle = attr.getString(R.styleable.FloatingActionButton_fab_title);
- mStrokeVisible = attr.getBoolean(R.styleable.FloatingActionButton_fab_stroke_visible, true);
- attr.recycle();
-
- updateCircleSize();
- mShadowRadius = getDimension(R.dimen.fab_shadow_radius);
- mShadowOffset = getDimension(R.dimen.fab_shadow_offset);
- updateDrawableSize();
-
- updateBackground();
- }
-
- private void updateDrawableSize() {
- mDrawableSize = (int) (mCircleSize + 2 * mShadowRadius);
- }
-
- private void updateCircleSize() {
- mCircleSize = getDimension(mSize == SIZE_NORMAL ? R.dimen.fab_size_normal : R.dimen.fab_size_mini);
- }
-
- @FAB_SIZE
- public int getSize() {
- return mSize;
- }
-
- public void setSize(@FAB_SIZE final int size) {
- if (size != SIZE_MINI && size != SIZE_NORMAL) {
- throw new IllegalArgumentException("Use @FAB_SIZE constants only!");
- }
-
- if (mSize != size) {
- mSize = size;
- updateCircleSize();
- updateDrawableSize();
- updateBackground();
- }
- }
-
- public void setIcon(@DrawableRes final int icon) {
- if (mIcon != icon) {
- mIcon = icon;
- mIconDrawable = null;
- updateBackground();
- }
- }
-
- /**
- * @return the current Color for normal state.
- */
- public int getColorNormal() {
- return mColorNormal;
- }
-
- public void setColorNormal(final int color) {
- if (mColorNormal != color) {
- mColorNormal = color;
- updateBackground();
- }
- }
-
- public void setColorNormalResId(@ColorRes final int colorNormal) {
- setColorNormal(ContextCompat.getColor(getContext(), colorNormal));
- }
-
- /**
- * @return the current color for pressed state.
- */
- public int getColorPressed() {
- return mColorPressed;
- }
-
- public void setColorPressed(final int color) {
- if (mColorPressed != color) {
- mColorPressed = color;
- updateBackground();
- }
- }
-
- public void setColorPressedResId(@ColorRes final int colorPressed) {
- setColorPressed(ContextCompat.getColor(getContext(), colorPressed));
- }
-
- /**
- * @return the current color for disabled state.
- */
- public int getColorDisabled() {
- return mColorDisabled;
- }
-
- public void setColorDisabled(final int color) {
- if (mColorDisabled != color) {
- mColorDisabled = color;
- updateBackground();
- }
- }
-
- public void setColorDisabledResId(@ColorRes final int colorDisabled) {
- setColorDisabled(ContextCompat.getColor(getContext(), colorDisabled));
- }
-
- public boolean isStrokeVisible() {
- return mStrokeVisible;
- }
-
- public void setStrokeVisible(final boolean visible) {
- if (mStrokeVisible != visible) {
- mStrokeVisible = visible;
- updateBackground();
- }
- }
-
- float getDimension(@DimenRes final int id) {
- return getResources().getDimension(id);
- }
-
- TextView getLabelView() {
- return (TextView) getTag(R.id.fab_label);
- }
-
- public String getTitle() {
- return mTitle;
- }
-
- public void setTitle(final String title) {
- mTitle = title;
- final TextView label = getLabelView();
- if (label != null) {
- label.setText(title);
- }
- }
-
- @Override
- protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- setMeasuredDimension(mDrawableSize, mDrawableSize);
- }
-
- void updateBackground() {
- final float strokeWidth = getDimension(R.dimen.fab_stroke_width);
- final float halfStrokeWidth = strokeWidth / 2f;
-
- final LayerDrawable layerDrawable = new LayerDrawable(
- new Drawable[]{
- //TODO(msf); replace these pngs with programatic elevation
- getResources().getDrawable(mSize == SIZE_NORMAL ? R.drawable.fab_bg_normal : R.drawable.fab_bg_mini, null),
- createFillDrawable(strokeWidth),
- createOuterStrokeDrawable(strokeWidth),
- getIconDrawable()
- });
-
- final int iconOffset = (int) (mCircleSize - getDimension(R.dimen.fab_icon_size)) / 2;
-
- final int circleInsetHorizontal = (int) (mShadowRadius);
- final int circleInsetTop = (int) (mShadowRadius - mShadowOffset);
- final int circleInsetBottom = (int) (mShadowRadius + mShadowOffset);
-
- layerDrawable.setLayerInset(1,
- circleInsetHorizontal,
- circleInsetTop,
- circleInsetHorizontal,
- circleInsetBottom);
-
- layerDrawable.setLayerInset(2,
- (int) (circleInsetHorizontal - halfStrokeWidth),
- (int) (circleInsetTop - halfStrokeWidth),
- (int) (circleInsetHorizontal - halfStrokeWidth),
- (int) (circleInsetBottom - halfStrokeWidth));
-
- layerDrawable.setLayerInset(3,
- circleInsetHorizontal + iconOffset,
- circleInsetTop + iconOffset,
- circleInsetHorizontal + iconOffset,
- circleInsetBottom + iconOffset);
-
- setBackground(layerDrawable);
- }
-
- Drawable getIconDrawable() {
- if (mIconDrawable != null) {
- return mIconDrawable;
- } else if (mIcon != 0) {
- return ContextCompat.getDrawable(getContext(), mIcon);
- } else {
- return new ColorDrawable(Color.TRANSPARENT);
- }
- }
-
- public void setIconDrawable(@NonNull final Drawable iconDrawable) {
- if (mIconDrawable != iconDrawable) {
- mIcon = 0;
- mIconDrawable = iconDrawable;
- updateBackground();
- }
- }
-
- private StateListDrawable createFillDrawable(final float strokeWidth) {
- final StateListDrawable drawable = new StateListDrawable();
- drawable.addState(new int[]{-android.R.attr.state_enabled}, createCircleDrawable(mColorDisabled, strokeWidth));
- drawable.addState(new int[]{android.R.attr.state_pressed}, createCircleDrawable(mColorPressed, strokeWidth));
- drawable.addState(new int[]{}, createCircleDrawable(mColorNormal, strokeWidth));
- return drawable;
- }
-
- private Drawable createCircleDrawable(final int color, final float strokeWidth) {
- final int alpha = Color.alpha(color);
- final int opaqueColor = opaque(color);
-
- final ShapeDrawable fillDrawable = new ShapeDrawable(new OvalShape());
-
- final Paint paint = fillDrawable.getPaint();
- paint.setAntiAlias(true);
- paint.setColor(opaqueColor);
-
- final Drawable[] layers = {
- fillDrawable,
- createInnerStrokesDrawable(opaqueColor, strokeWidth)
- };
-
- final LayerDrawable drawable = alpha == 255 || !mStrokeVisible
- ? new LayerDrawable(layers)
- : new TranslucentLayerDrawable(alpha, layers);
-
- final int halfStrokeWidth = (int) (strokeWidth / 2f);
- drawable.setLayerInset(1, halfStrokeWidth, halfStrokeWidth, halfStrokeWidth, halfStrokeWidth);
-
- return drawable;
- }
-
- private static Drawable createOuterStrokeDrawable(final float strokeWidth) {
- final ShapeDrawable shapeDrawable = new ShapeDrawable(new OvalShape());
-
- final Paint paint = shapeDrawable.getPaint();
- paint.setAntiAlias(true);
- paint.setStrokeWidth(strokeWidth);
- paint.setStyle(Style.STROKE);
- paint.setColor(Color.BLACK);
- paint.setAlpha(opacityToAlpha(0.02f));
-
- return shapeDrawable;
- }
-
- private static int opacityToAlpha(final float opacity) {
- return (int) (255f * opacity);
- }
-
- private static int darkenColor(final int argb) {
- return adjustColorBrightness(argb, 0.9f);
- }
-
- private static int lightenColor(final int argb) {
- return adjustColorBrightness(argb, 1.1f);
- }
-
- public static int darkenOrLightenColor(final int argb) {
- final float[] hsv = new float[3];
- Color.colorToHSV(argb, hsv);
- final float factor;
- if (hsv[2] < 0.2)
- factor = 1.2f;
- else
- factor = 0.8f;
-
- hsv[2] = Math.min(hsv[2] * factor, 1f);
- return Color.HSVToColor(Color.alpha(argb), hsv);
- }
-
- private static int adjustColorBrightness(final int argb, final float factor) {
- final float[] hsv = new float[3];
- Color.colorToHSV(argb, hsv);
-
- hsv[2] = Math.min(hsv[2] * factor, 1f);
-
- return Color.HSVToColor(Color.alpha(argb), hsv);
- }
-
- private static int halfTransparent(final int argb) {
- return Color.argb(
- Color.alpha(argb) / 2,
- Color.red(argb),
- Color.green(argb),
- Color.blue(argb)
- );
- }
-
- private static int opaque(final int argb) {
- return Color.rgb(
- Color.red(argb),
- Color.green(argb),
- Color.blue(argb)
- );
- }
-
- private Drawable createInnerStrokesDrawable(final int color, final float strokeWidth) {
- if (!mStrokeVisible) {
- return new ColorDrawable(Color.TRANSPARENT);
- }
-
- final ShapeDrawable shapeDrawable = new ShapeDrawable(new OvalShape());
-
- final int bottomStrokeColor = darkenColor(color);
- final int bottomStrokeColorHalfTransparent = halfTransparent(bottomStrokeColor);
- final int topStrokeColor = lightenColor(color);
- final int topStrokeColorHalfTransparent = halfTransparent(topStrokeColor);
-
- final Paint paint = shapeDrawable.getPaint();
- paint.setAntiAlias(true);
- paint.setStrokeWidth(strokeWidth);
- paint.setStyle(Style.STROKE);
- shapeDrawable.setShaderFactory(new ShaderFactory() {
- @Override
- public Shader resize(int width, int height) {
- return new LinearGradient(width / 2, 0, width / 2, height,
- new int[]{topStrokeColor, topStrokeColorHalfTransparent, color, bottomStrokeColorHalfTransparent, bottomStrokeColor},
- new float[]{0f, 0.2f, 0.5f, 0.8f, 1f},
- TileMode.CLAMP
- );
- }
- });
-
- return shapeDrawable;
- }
-
- @Override
- public void setVisibility(final int visibility) {
- final TextView label = getLabelView();
- if (label != null) {
- label.setVisibility(visibility);
- }
-
- super.setVisibility(visibility);
- }
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({SIZE_NORMAL, SIZE_MINI})
- public @interface FAB_SIZE {
- }
-
- private static final class TranslucentLayerDrawable extends LayerDrawable {
- private final int mAlpha;
-
- private TranslucentLayerDrawable(final int alpha, final Drawable... layers) {
- super(layers);
- mAlpha = alpha;
- }
-
- @Override
- public void draw(final Canvas canvas) {
- final Rect bounds = getBounds();
- canvas.saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom, mAlpha);
- super.draw(canvas);
- canvas.restore();
- }
- }
-}