/* * Overchan Android (Meta Imageboard Client) * Copyright (C) 2014-2016 miku-nyan <https://github.com/miku-nyan> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package nya.miku.wishmaster.ui.theme; import nya.miku.wishmaster.R; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.os.Build; import android.support.v4.content.res.ResourcesCompat; import android.util.TypedValue; public class ThemeUtils { private ThemeUtils() {} private static void resolveAttribute(Theme theme, int attrId, TypedValue outValue, boolean resolveRefs) { if (CustomThemeHelper.resolveAttribute(attrId, outValue)) return; if (!theme.resolveAttribute(attrId, outValue, resolveRefs)) outValue.type = TypedValue.TYPE_NULL; } private static int getThemeColor(TypedValue tmp, Theme theme, int attrId, int defaultValue) { if (tmp == null) tmp = new TypedValue(); resolveAttribute(theme, attrId, tmp, true); if (tmp.type >= TypedValue.TYPE_FIRST_COLOR_INT && tmp.type <= TypedValue.TYPE_LAST_COLOR_INT) { return tmp.data; } else { return defaultValue; } } /** * Получить значение атрибута в теме (создаётся объект TypedValue) * @param theme тема * @param attrId id атрибута (R.attr.[...]) * @param resolveRefs если true, ссылки (ресурсы) будут разрешены; если false, значение может быть типа TYPE_REFERENCE. * В любом случае оно не будет типа TYPE_ATTRIBUTE. * @return объект TypedValue */ public static TypedValue resolveAttribute(Theme theme, int attrId, boolean resolveRefs) { TypedValue typedValue = new TypedValue(); resolveAttribute(theme, attrId, typedValue, resolveRefs); return typedValue; } /** * Получить ID ресурса для данной темы из аттрибута * @param theme тема * @param attrId id атрибута (R.attr.[...]) * @return ID ресурса */ public static int getThemeResId(Theme theme, int attrId) { return resolveAttribute(theme, attrId, true).resourceId; } /** * Получить цвет данной темы из атрибута * @param theme тема * @param attrId id атрибута (R.attr.[...]) * @param defaultValue значение по умолчанию, если получить не удалось * @return цвет в виде int */ public static int getThemeColor(Theme theme, int attrId, int defaultValue) { return getThemeColor(null, theme, attrId, defaultValue); } /** * Получить значок (drawable) для Action Bar. В случае Android 5.0 и выше значок перекрашивается в цвет android:attr/textColorPrimary * @param theme тема * @param resources ресурсы * @param attrId id атрибута (R.attr.[...]) * @return объект Drawable со значком, или null, если не удалось получить */ public static Drawable getActionbarIcon(Theme theme, Resources resources, int attrId) { try { int id = getThemeResId(theme, attrId); Drawable drawable = ResourcesCompat.getDrawable(resources, id, theme); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { int color = getThemeColor(theme, android.R.attr.textColorPrimary, Color.TRANSPARENT); if (color != Color.TRANSPARENT) { drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); } } return drawable; } catch (Exception e) { return null; } } /** * Объект, содержащий цвета, нужные при программной обработке (парсинг html, создание заголовков постов) * @author miku-nyan * */ public static class ThemeColors { private static ThemeColors instance = null; private static Theme currentTheme = null; public final int indexForeground; public final int indexOverBumpLimit; public final int numberForeground; public final int nameForeground; public final int opForeground; public final int sageForeground; public final int tripForeground; public final int subscriptionBackground; public final int quoteForeground; public final int spoilerForeground; public final int spoilerBackground; public final int urlLinkForeground; public final int refererForeground; public final int subjectForeground; private ThemeColors(int indexForeground, int indexBumpLimit, int numberForeground, int nameForeground, int opForeground, int sageForeground, int tripForeground, int subscriptionBackground, int quoteForeground, int spoilerForeground, int spoilerBackground, int urlLinkForeground, int refererForeground, int subjectForeground) { this.indexForeground = indexForeground; this.indexOverBumpLimit = indexBumpLimit; this.numberForeground = numberForeground; this.nameForeground = nameForeground; this.opForeground = opForeground; this.sageForeground = sageForeground; this.tripForeground = tripForeground; this.subscriptionBackground = subscriptionBackground; this.quoteForeground = quoteForeground; this.spoilerForeground = spoilerForeground; this.spoilerBackground = spoilerBackground; this.urlLinkForeground = urlLinkForeground; this.refererForeground = refererForeground; this.subjectForeground = subjectForeground; } /** * Получить экземпляр с цветами заданной темы * @param theme тема * @return объект ThemeColors */ public static ThemeColors getInstance(Theme theme) { if (instance == null || currentTheme != theme) { currentTheme = theme; TypedValue tmp = new TypedValue(); int indexColor = ThemeUtils.getThemeColor(tmp, theme, R.attr.postIndexForeground, Color.parseColor("#4F7942")); int overBumpLimitColor = ThemeUtils.getThemeColor(tmp, theme, R.attr.postIndexOverBumpLimit, Color.parseColor("#C41E3A")); int numberColor = ThemeUtils.getThemeColor(tmp, theme, R.attr.postNumberForeground, Color.BLACK); int nameColor = ThemeUtils.getThemeColor(tmp, theme, R.attr.postNameForeground, Color.BLACK); int opColor = ThemeUtils.getThemeColor(tmp, theme, R.attr.postOpForeground, Color.parseColor("#008000")); int sageColor = ThemeUtils.getThemeColor(tmp, theme, R.attr.postSageForeground, Color.parseColor("#993333")); int tripColor = ThemeUtils.getThemeColor(tmp, theme, R.attr.postTripForeground, Color.parseColor("#228854")); int subscriptionBackground = ThemeUtils.getThemeColor(tmp, theme, R.attr.subscriptionBackground, Color.parseColor("#CCCCCC")); int quoteForeground = ThemeUtils.getThemeColor(tmp, theme, R.attr.postQuoteForeground, Color.parseColor("#789922")); int spoilerForeground = ThemeUtils.getThemeColor(tmp, theme, R.attr.spoilerForeground, Color.BLACK); int spoilerBackground = ThemeUtils.getThemeColor(tmp, theme, R.attr.spoilerBackground, Color.parseColor("#BBBBBB")); int urlLinkForeground = ThemeUtils.getThemeColor(tmp, theme, R.attr.urlLinkForeground, Color.parseColor("#0000EE")); int refererForeground = ThemeUtils.getThemeColor(tmp, theme, R.attr.refererForeground, Color.parseColor("#FF0000")); int subjectForeground = ThemeUtils.getThemeColor(tmp, theme, R.attr.postTitleForeground, Color.BLACK); instance = new ThemeColors( indexColor, overBumpLimitColor, numberColor, nameColor, opColor, sageColor, tripColor, subscriptionBackground, quoteForeground, spoilerForeground, spoilerBackground, urlLinkForeground, refererForeground, subjectForeground); } return instance; } } }