/*
* Copyright (C) 2014 OpenSilk Productions LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opensilk.common.ui.util;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.Toolbar;
import android.util.TypedValue;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import org.opensilk.common.core.util.VersionUtils;
import org.opensilk.common.ui.R;
import org.opensilk.common.ui.widget.CompatSeekBar;
/**
* Created by drew on 10/12/14.
*/
public class ThemeUtils {
private static final TypedValue sTypedValue = new TypedValue();
public static TypedValue resolveAttr(Context context, int attr) {
TypedValue outValue = new TypedValue();
context.getTheme().resolveAttribute(attr, outValue, true);
return outValue;
}
public static int getColorPrimary(Context context) {
return getThemeAttrColor(context, R.attr.colorPrimary);
}
public static int getColorAccent(Context context) {
return getThemeAttrColor(context, R.attr.colorAccent);
}
public static int getColorPrimaryDark(Context context) {
return getThemeAttrColor(context, R.attr.colorPrimaryDark);
}
public static int getColorControlNormal(Context context) {
return getThemeAttrColor(context, R.attr.colorControlNormal);
}
public static int getColorControlActivited(Context context) {
return getThemeAttrColor(context, R.attr.colorControlActivated);
}
public static int getColorControlHighlight(Context context) {
return getThemeAttrColor(context, R.attr.colorControlHighlight);
}
public static int getColorButtonNormal(Context context) {
return getThemeAttrColor(context, R.attr.colorButtonNormal);
}
public static int getColorSwitchThumbNormal(Context context) {
return getThemeAttrColor(context, R.attr.colorSwitchThumbNormal);
}
public static int setColorAlpha(int color, int alpha) {
return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
}
/**
* MediaRouterThemeHelper (support-v7)
*/
public static boolean isLightTheme(Context context) {
synchronized (sTypedValue) {
return context.getTheme().resolveAttribute(R.attr.isLightTheme, sTypedValue, true) && sTypedValue.data != 0;
}
}
/*
* TintManager (support-v7:21)
*/
public static int getThemeAttrColor(Context context, int attr) {
synchronized (sTypedValue) {
if (context.getTheme().resolveAttribute(attr, sTypedValue, true)) {
if (sTypedValue.type >= TypedValue.TYPE_FIRST_INT
&& sTypedValue.type <= TypedValue.TYPE_LAST_INT) {
return sTypedValue.data;
} else if (sTypedValue.type == TypedValue.TYPE_STRING) {
return ContextCompat.getColor(context, sTypedValue.resourceId);
}
}
}
return 0;
}
public static int getThemeAttrColor(Context context, int attr, float alpha) {
final int color = getThemeAttrColor(context, attr);
final int originalAlpha = Color.alpha(color);
// Return the color, multiplying the original alpha by the disabled value
return (color & 0x00ffffff) | (Math.round(originalAlpha * alpha) << 24);
}
public static int getDisabledThemeAttrColor(Context context, int attr) {
// Now retrieve the disabledAlpha value from the theme
final float disabledAlpha;
synchronized (sTypedValue) {
context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, sTypedValue, true);
disabledAlpha = sTypedValue.getFloat();
}
return getThemeAttrColor(context, attr, disabledAlpha);
}
public static ColorStateList getDefaultColorStateList(Context context) {
/**
* Generate the default color state list which uses the colorControl attributes.
* Order is important here. The default enabled state needs to go at the bottom.
*/
final int colorControlNormal = getThemeAttrColor(context, R.attr.colorControlNormal);
final int colorControlActivated = getThemeAttrColor(context, R.attr.colorControlActivated);
final int[][] states = new int[7][];
final int[] colors = new int[7];
int i = 0;
// Disabled state
states[i] = new int[] { -android.R.attr.state_enabled };
colors[i] = getDisabledThemeAttrColor(context, R.attr.colorControlNormal);
i++;
states[i] = new int[] { android.R.attr.state_focused };
colors[i] = colorControlActivated;
i++;
states[i] = new int[] { android.R.attr.state_activated };
colors[i] = colorControlActivated;
i++;
states[i] = new int[] { android.R.attr.state_pressed };
colors[i] = colorControlActivated;
i++;
states[i] = new int[] { android.R.attr.state_checked };
colors[i] = colorControlActivated;
i++;
states[i] = new int[] { android.R.attr.state_selected };
colors[i] = colorControlActivated;
i++;
// Default enabled state
states[i] = new int[0];
colors[i] = colorControlNormal;
i++;
return new ColorStateList(states, colors);
}
public static void themeToolbar(Toolbar toolbar) {
toolbar.setBackgroundColor(getColorPrimary(toolbar.getContext()));
}
public static void themeSeekBar(SeekBar seekBar, int colorAttr) {
themeSeekBar2(seekBar, getThemeAttrColor(seekBar.getContext(), colorAttr));
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static void themeSeekBar2(SeekBar seekBar, int color) {
if (VersionUtils.hasLollipop()) {
seekBar.getProgressDrawable().setTint(color);
seekBar.getThumb().setTint(color);
} else {
seekBar.getProgressDrawable().mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
if (VersionUtils.hasJellyBean()) {
seekBar.getThumb().mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
} else if (seekBar instanceof CompatSeekBar) {
Drawable thumb = ((CompatSeekBar) seekBar).getThumb();
if (thumb != null) {
thumb.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
}
}
}
public static void themeProgressBar(ProgressBar progressBar, int colorAttr) {
themeProgressBar2(progressBar, getThemeAttrColor(progressBar.getContext(), colorAttr));
}
@TargetApi(21)
public static void themeProgressBar2(ProgressBar progressBar, int color) {
if (VersionUtils.hasLollipop()) {
progressBar.getProgressDrawable().setTint(color);
progressBar.getIndeterminateDrawable().setTint(color);
} else {
progressBar.getProgressDrawable().mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
progressBar.getIndeterminateDrawable().mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
}
public static Drawable colorizeBitmapDrawableCopy(Context context, int resId, int newColor) {
final Drawable maskDrawable = context.getResources().getDrawable(resId);
if (!(maskDrawable instanceof BitmapDrawable)) {
return null;
}
final Bitmap maskBitmap = ((BitmapDrawable) maskDrawable).getBitmap();
final int width = maskBitmap.getWidth();
final int height = maskBitmap.getHeight();
final Bitmap outBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(outBitmap);
canvas.drawBitmap(maskBitmap, 0, 0, null);
final Paint maskedPaint = new Paint();
maskedPaint.setColor(newColor);
maskedPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawRect(0, 0, width, height, maskedPaint);
return new BitmapDrawable(context.getResources(), outBitmap);
}
}