2014-07-03 07:48:39 +02:00
|
|
|
/*
|
|
|
|
* Twidere - Twitter client for Android
|
|
|
|
*
|
|
|
|
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
|
|
|
*
|
|
|
|
* 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 org.mariotaku.twidere.util;
|
|
|
|
|
|
|
|
import android.app.Activity;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.res.Resources;
|
|
|
|
import android.content.res.TypedArray;
|
|
|
|
import android.graphics.Color;
|
2014-10-29 07:48:07 +01:00
|
|
|
import android.graphics.PorterDuff.Mode;
|
2014-07-03 07:48:39 +02:00
|
|
|
import android.graphics.Typeface;
|
2014-12-01 17:04:55 +01:00
|
|
|
import android.graphics.drawable.ColorDrawable;
|
2014-07-03 07:48:39 +02:00
|
|
|
import android.graphics.drawable.Drawable;
|
|
|
|
import android.os.Build;
|
2014-08-07 19:58:42 +02:00
|
|
|
import android.support.annotation.NonNull;
|
2015-04-17 04:54:48 +02:00
|
|
|
import android.support.annotation.Nullable;
|
2015-04-03 17:49:08 +02:00
|
|
|
import android.support.v4.app.FragmentActivity;
|
|
|
|
import android.support.v4.view.ViewCompat;
|
2015-05-03 16:43:05 +02:00
|
|
|
import android.support.v7.app.ActionBar;
|
2015-04-03 23:12:33 +02:00
|
|
|
import android.support.v7.internal.app.WindowDecorActionBar;
|
|
|
|
import android.support.v7.internal.app.WindowDecorActionBar.ActionModeImpl;
|
2015-04-27 18:47:31 +02:00
|
|
|
import android.support.v7.internal.view.StandaloneActionMode;
|
2015-01-17 19:58:29 +01:00
|
|
|
import android.support.v7.internal.view.menu.ActionMenuItemView;
|
2015-04-27 19:57:39 +02:00
|
|
|
import android.support.v7.internal.widget.ActionBarContainer;
|
2015-04-17 04:54:48 +02:00
|
|
|
import android.support.v7.internal.widget.ActionBarContextView;
|
2015-04-04 00:06:08 +02:00
|
|
|
import android.support.v7.internal.widget.ActionBarOverlayLayout;
|
2015-04-17 09:17:22 +02:00
|
|
|
import android.support.v7.internal.widget.ContentFrameLayout;
|
2015-04-28 09:18:20 +02:00
|
|
|
import android.support.v7.widget.ActionMenuPresenter;
|
2015-01-17 19:58:29 +01:00
|
|
|
import android.support.v7.widget.ActionMenuView;
|
2015-04-13 18:34:10 +02:00
|
|
|
import android.support.v7.widget.Toolbar;
|
2014-11-22 15:12:54 +01:00
|
|
|
import android.text.SpannableStringBuilder;
|
|
|
|
import android.text.Spanned;
|
2014-07-03 07:48:39 +02:00
|
|
|
import android.text.TextPaint;
|
|
|
|
import android.text.TextUtils;
|
2015-04-27 14:25:26 +02:00
|
|
|
import android.util.TypedValue;
|
2014-10-25 12:45:50 +02:00
|
|
|
import android.view.ContextMenu.ContextMenuInfo;
|
2014-07-03 07:48:39 +02:00
|
|
|
import android.view.ContextThemeWrapper;
|
2014-10-25 12:45:50 +02:00
|
|
|
import android.view.Menu;
|
|
|
|
import android.view.MenuItem;
|
2014-07-03 07:48:39 +02:00
|
|
|
import android.view.View;
|
2015-01-17 19:58:29 +01:00
|
|
|
import android.view.View.OnLongClickListener;
|
2015-04-13 18:34:10 +02:00
|
|
|
import android.view.Window;
|
2015-04-14 17:38:50 +02:00
|
|
|
import android.view.WindowManager;
|
2015-04-13 18:34:10 +02:00
|
|
|
import android.widget.ImageView;
|
2014-10-29 07:48:07 +01:00
|
|
|
import android.widget.TextView;
|
2014-07-03 07:48:39 +02:00
|
|
|
|
2015-01-11 10:28:45 +01:00
|
|
|
import org.apache.commons.lang3.ArrayUtils;
|
2014-07-03 07:48:39 +02:00
|
|
|
import org.mariotaku.twidere.Constants;
|
|
|
|
import org.mariotaku.twidere.R;
|
|
|
|
import org.mariotaku.twidere.activity.iface.IThemedActivity;
|
2014-12-08 16:16:33 +01:00
|
|
|
import org.mariotaku.twidere.graphic.ActionBarColorDrawable;
|
2015-01-17 19:58:29 +01:00
|
|
|
import org.mariotaku.twidere.graphic.ActionIconDrawable;
|
2015-05-17 17:16:54 +02:00
|
|
|
import org.mariotaku.twidere.preference.ThemeBackgroundPreference;
|
2014-11-22 15:12:54 +01:00
|
|
|
import org.mariotaku.twidere.text.ParagraphSpacingSpan;
|
2014-11-03 16:44:32 +01:00
|
|
|
import org.mariotaku.twidere.util.menu.TwidereMenuInfo;
|
2015-04-27 14:25:26 +02:00
|
|
|
import org.mariotaku.twidere.util.support.ViewSupport;
|
2015-04-03 17:49:08 +02:00
|
|
|
import org.mariotaku.twidere.view.TabPagerIndicator;
|
2015-04-30 11:55:03 +02:00
|
|
|
import org.mariotaku.twidere.view.TwidereToolbar;
|
2014-07-03 07:48:39 +02:00
|
|
|
|
2015-04-03 23:12:33 +02:00
|
|
|
import java.lang.reflect.Field;
|
2014-07-03 07:48:39 +02:00
|
|
|
|
|
|
|
public class ThemeUtils implements Constants {
|
|
|
|
|
2015-04-26 15:46:23 +02:00
|
|
|
public static final int ACCENT_COLOR_THRESHOLD = 192;
|
|
|
|
|
2014-07-27 14:58:15 +02:00
|
|
|
private static final int[] ANIM_OPEN_STYLE_ATTRS = {android.R.attr.activityOpenEnterAnimation,
|
|
|
|
android.R.attr.activityOpenExitAnimation};
|
|
|
|
private static final int[] ANIM_CLOSE_STYLE_ATTRS = {android.R.attr.activityCloseEnterAnimation,
|
|
|
|
android.R.attr.activityCloseExitAnimation};
|
2015-04-26 12:55:41 +02:00
|
|
|
public static final int[] ATTRS_TEXT_COLOR_PRIMARY = {android.R.attr.textColorPrimary};
|
|
|
|
public static final int[] ATTRS_TEXT_COLOR_PRIMARY_INVERSE = {android.R.attr.textColorPrimaryInverse};
|
2015-04-26 15:46:23 +02:00
|
|
|
public static final int[] ATTRS_TEXT_COLOR_PRIMARY_AND_INVERSE = {android.R.attr.textColorPrimary,
|
|
|
|
android.R.attr.textColorPrimaryInverse};
|
|
|
|
public static final int[] ATTRS_COLOR_FOREGROUND_AND_INVERSE = {android.R.attr.colorForeground,
|
|
|
|
android.R.attr.colorForegroundInverse};
|
2014-07-27 14:58:15 +02:00
|
|
|
|
|
|
|
private ThemeUtils() {
|
|
|
|
throw new AssertionError();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-12-01 17:04:55 +01:00
|
|
|
public static void applyActionBarBackground(final ActionBar actionBar, final Context context,
|
2015-04-16 22:29:36 +02:00
|
|
|
final int themeRes, final int accentColor, String backgroundOption, boolean outlineEnabled) {
|
2015-01-17 19:58:29 +01:00
|
|
|
if (actionBar == null || context == null) return;
|
2015-04-16 22:29:36 +02:00
|
|
|
actionBar.setBackgroundDrawable(getActionBarBackground(context, themeRes, accentColor, backgroundOption, outlineEnabled));
|
2015-01-17 19:58:29 +01:00
|
|
|
actionBar.setSplitBackgroundDrawable(getActionBarSplitBackground(context, themeRes));
|
2015-05-12 17:47:52 +02:00
|
|
|
actionBar.setStackedBackgroundDrawable(getActionBarStackedBackground(context, themeRes, accentColor, backgroundOption, outlineEnabled));
|
2015-01-17 19:58:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-04-27 19:57:39 +02:00
|
|
|
public static void applyActionBarBackground(final ActionBarContainer actionBar, final Context context,
|
|
|
|
final int themeRes, final int accentColor, String backgroundOption, boolean outlineEnabled) {
|
|
|
|
if (actionBar == null || context == null) return;
|
|
|
|
actionBar.setPrimaryBackground(getActionBarBackground(context, themeRes, accentColor, backgroundOption, outlineEnabled));
|
|
|
|
actionBar.setSplitBackground(getActionBarSplitBackground(context, themeRes));
|
2015-05-12 17:47:52 +02:00
|
|
|
actionBar.setStackedBackground(getActionBarStackedBackground(context, themeRes, accentColor, backgroundOption, outlineEnabled));
|
2015-04-27 19:57:39 +02:00
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static void applyColorFilterToMenuIcon(final Menu menu, final int color, final int popupColor,
|
|
|
|
final int highlightColor, final Mode mode,
|
|
|
|
final int... excludedGroups) {
|
|
|
|
for (int i = 0, j = menu.size(); i < j; i++) {
|
|
|
|
final MenuItem item = menu.getItem(i);
|
|
|
|
final Drawable icon = item.getIcon();
|
|
|
|
final ContextMenuInfo info = item.getMenuInfo();
|
|
|
|
if (icon != null && !ArrayUtils.contains(excludedGroups, item.getGroupId())) {
|
|
|
|
icon.mutate();
|
|
|
|
if (info instanceof TwidereMenuInfo) {
|
|
|
|
final TwidereMenuInfo sInfo = (TwidereMenuInfo) info;
|
|
|
|
icon.setColorFilter(sInfo.isHighlight() ?
|
|
|
|
sInfo.getHighlightColor(highlightColor) : color, mode);
|
|
|
|
} else {
|
|
|
|
icon.setColorFilter(color, mode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (item.hasSubMenu()) {
|
|
|
|
// SubMenu item is always in popup
|
|
|
|
applyColorFilterToMenuIcon(item.getSubMenu(), popupColor, popupColor, highlightColor, mode, excludedGroups);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void applyParagraphSpacing(TextView textView, float multiplier) {
|
|
|
|
final SpannableStringBuilder builder = SpannableStringBuilder.valueOf(textView.getText());
|
|
|
|
int prevLineBreak, currLineBreak = 0;
|
|
|
|
for (int i = 0, j = builder.length(); i < j; i++) {
|
|
|
|
if (builder.charAt(i) == '\n') {
|
|
|
|
prevLineBreak = currLineBreak;
|
|
|
|
currLineBreak = i;
|
|
|
|
if (currLineBreak > 0) {
|
|
|
|
builder.setSpan(new ParagraphSpacingSpan(multiplier), prevLineBreak, currLineBreak,
|
|
|
|
Spanned.SPAN_INCLUSIVE_INCLUSIVE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
textView.setText(builder);
|
|
|
|
}
|
|
|
|
|
2015-04-22 16:19:26 +02:00
|
|
|
public static void applySupportActionModeColor(final android.support.v7.view.ActionMode modeCompat,
|
|
|
|
Activity activity, int themeRes,
|
2015-04-17 04:54:48 +02:00
|
|
|
int accentColor, String backgroundOption,
|
|
|
|
boolean outlineEnabled) {
|
2015-04-16 22:29:36 +02:00
|
|
|
// Very dirty implementation
|
2015-04-26 12:55:41 +02:00
|
|
|
// This call ensures TitleView created
|
2015-05-03 16:43:05 +02:00
|
|
|
modeCompat.setTitle(modeCompat.getTitle());
|
|
|
|
View contextView = null;
|
|
|
|
if (modeCompat instanceof ActionModeImpl) {
|
|
|
|
WindowDecorActionBar actionBar = (WindowDecorActionBar) Utils.findFieldOfTypes(modeCompat,
|
|
|
|
ActionModeImpl.class, WindowDecorActionBar.class);
|
|
|
|
if (actionBar == null) return;
|
|
|
|
contextView = (View) Utils.findFieldOfTypes(actionBar, WindowDecorActionBar.class,
|
|
|
|
ActionBarContextView.class);
|
|
|
|
} else if (modeCompat instanceof StandaloneActionMode) {
|
|
|
|
contextView = (View) Utils.findFieldOfTypes(modeCompat, StandaloneActionMode.class,
|
|
|
|
ActionBarContextView.class);
|
|
|
|
}
|
|
|
|
if (!(contextView instanceof ActionBarContextView)) return;
|
|
|
|
setActionBarContextViewBackground((ActionBarContextView) contextView, themeRes,
|
|
|
|
accentColor, backgroundOption, outlineEnabled);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void setActionBarContextViewBackground(@NonNull ActionBarContextView contextView,
|
|
|
|
int themeRes, int accentColor,
|
|
|
|
String backgroundOption, boolean outlineEnabled) {
|
|
|
|
ViewSupport.setBackground(contextView, getActionBarBackground(contextView.getContext(),
|
|
|
|
themeRes, accentColor, backgroundOption, outlineEnabled));
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void setActionBarContextViewColor(@NonNull ActionBarContextView contextView,
|
|
|
|
int itemColor) {
|
2015-05-02 14:55:16 +02:00
|
|
|
contextView.setTitle(contextView.getTitle());
|
|
|
|
contextView.setSubtitle(contextView.getSubtitle());
|
2015-04-27 18:47:31 +02:00
|
|
|
final ImageView actionModeCloseButton = (ImageView) contextView.findViewById(android.support.v7.appcompat.R.id.action_mode_close_button);
|
|
|
|
final ActionMenuView menuView = ViewSupport.findViewByType(contextView, ActionMenuView.class);
|
|
|
|
if (actionModeCloseButton != null) {
|
|
|
|
actionModeCloseButton.setColorFilter(itemColor, Mode.SRC_ATOP);
|
|
|
|
}
|
|
|
|
if (menuView != null) {
|
|
|
|
setActionBarOverflowColor(menuView, itemColor);
|
|
|
|
ThemeUtils.wrapToolbarMenuIcon(menuView, itemColor, itemColor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-13 08:45:52 +02:00
|
|
|
public static void applyWindowBackground(@NonNull Context context, @NonNull Window window, int theme, String option, int alpha) {
|
2015-04-14 17:42:46 +02:00
|
|
|
if (isWindowFloating(context, theme)) return;
|
2015-05-05 07:46:29 +02:00
|
|
|
final int normalTheme = getThemeResource(theme);
|
2015-04-14 17:38:50 +02:00
|
|
|
if (VALUE_THEME_BACKGROUND_TRANSPARENT.equals(option)) {
|
|
|
|
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);
|
2015-05-05 07:46:29 +02:00
|
|
|
window.setBackgroundDrawable(getWindowBackgroundFromThemeApplyAlpha(context, normalTheme, alpha));
|
2015-04-14 17:38:50 +02:00
|
|
|
} else if (VALUE_THEME_BACKGROUND_SOLID.equals(option)) {
|
2015-05-05 07:46:29 +02:00
|
|
|
window.setBackgroundDrawable(new ColorDrawable(isDarkTheme(normalTheme) ? Color.BLACK : Color.WHITE));
|
|
|
|
} else {
|
|
|
|
window.setBackgroundDrawable(getWindowBackgroundFromTheme(context, normalTheme));
|
2015-04-14 17:38:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static void applyWindowBackground(Context context, View window, int theme, String option, int alpha) {
|
|
|
|
if (isWindowFloating(context, theme)) return;
|
2015-05-05 07:46:29 +02:00
|
|
|
final int normalTheme = getThemeResource(theme);
|
2015-04-15 13:14:47 +02:00
|
|
|
if (VALUE_THEME_BACKGROUND_TRANSPARENT.equals(option)) {
|
2015-05-05 07:46:29 +02:00
|
|
|
ViewSupport.setBackground(window, getWindowBackgroundFromThemeApplyAlpha(context, normalTheme, alpha));
|
2015-04-15 13:14:47 +02:00
|
|
|
} else if (VALUE_THEME_BACKGROUND_SOLID.equals(option)) {
|
2015-05-05 07:46:29 +02:00
|
|
|
ViewSupport.setBackground(window, new ColorDrawable(isDarkTheme(normalTheme) ? Color.BLACK : Color.WHITE));
|
2015-04-15 13:14:47 +02:00
|
|
|
} else {
|
2015-05-05 07:46:29 +02:00
|
|
|
ViewSupport.setBackground(window, getWindowBackgroundFromTheme(context, normalTheme));
|
2015-04-04 00:06:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-14 17:38:50 +02:00
|
|
|
|
2015-04-16 22:29:36 +02:00
|
|
|
@NonNull
|
|
|
|
public static Drawable getActionBarBackground(final Context context, final int themeRes,
|
|
|
|
final int accentColor, final String backgroundOption,
|
|
|
|
final boolean outlineEnabled) {
|
|
|
|
final int actionBarColor;
|
2015-05-11 18:36:18 +02:00
|
|
|
if (!isDarkTheme(themeRes)) {
|
2015-04-16 22:29:36 +02:00
|
|
|
actionBarColor = accentColor;
|
2015-05-11 18:36:18 +02:00
|
|
|
} else if (isSolidBackground(backgroundOption)) {
|
|
|
|
actionBarColor = Color.BLACK;
|
|
|
|
} else {
|
|
|
|
actionBarColor = context.getResources().getColor(R.color.background_color_action_bar_dark);
|
2015-04-16 22:29:36 +02:00
|
|
|
}
|
2015-04-17 16:36:04 +02:00
|
|
|
return ActionBarColorDrawable.create(actionBarColor, outlineEnabled);
|
2015-04-16 22:29:36 +02:00
|
|
|
}
|
|
|
|
|
2015-05-17 12:14:29 +02:00
|
|
|
public static int getActionBarPopupThemeRes(final Context context, int def) {
|
|
|
|
final TypedValue outValue = new TypedValue();
|
|
|
|
if (context.getTheme().resolveAttribute(R.attr.actionBarPopupTheme, outValue, true)) {
|
|
|
|
return outValue.resourceId;
|
2015-04-13 18:34:10 +02:00
|
|
|
}
|
2015-05-17 12:14:29 +02:00
|
|
|
return def;
|
2015-01-17 19:58:29 +01:00
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static Drawable getActionBarSplitBackground(final Context context, final int themeRes) {
|
|
|
|
@SuppressWarnings("ConstantConditions")
|
|
|
|
final TypedArray a = context.obtainStyledAttributes(null, new int[]{android.R.attr.backgroundSplit},
|
|
|
|
android.R.attr.actionBarStyle, themeRes);
|
2015-04-17 16:36:04 +02:00
|
|
|
try {
|
|
|
|
return a.getDrawable(0);
|
|
|
|
} finally {
|
|
|
|
a.recycle();
|
|
|
|
}
|
2015-04-15 13:14:47 +02:00
|
|
|
}
|
2015-04-13 18:34:10 +02:00
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
@NonNull
|
|
|
|
public static Drawable getActionBarStackedBackground(final Context context, final int themeRes,
|
2015-05-12 17:47:52 +02:00
|
|
|
final int accentColor, String backgroundOption,
|
|
|
|
boolean outlineEnabled) {
|
|
|
|
return getActionBarBackground(context, themeRes, accentColor, backgroundOption, outlineEnabled);
|
2015-04-13 18:34:10 +02:00
|
|
|
}
|
|
|
|
|
2015-04-17 16:36:04 +02:00
|
|
|
public static int getCardBackgroundColor(final Context context, String backgroundOption, int themeAlpha) {
|
2015-04-15 13:14:47 +02:00
|
|
|
final TypedArray a = context.obtainStyledAttributes(new int[]{R.attr.cardItemBackgroundColor});
|
|
|
|
final int color = a.getColor(0, Color.TRANSPARENT);
|
|
|
|
a.recycle();
|
2015-04-17 16:36:04 +02:00
|
|
|
if (isTransparentBackground(backgroundOption)) {
|
|
|
|
return themeAlpha << 24 | (0x00FFFFFF & color);
|
|
|
|
} else if (isSolidBackground(backgroundOption)) {
|
2015-04-22 10:36:56 +02:00
|
|
|
return TwidereColorUtils.getContrastYIQ(color, Color.WHITE, Color.BLACK);
|
2015-04-17 16:36:04 +02:00
|
|
|
} else {
|
|
|
|
return color;
|
|
|
|
}
|
2015-03-19 17:19:57 +01:00
|
|
|
}
|
2015-01-17 19:58:29 +01:00
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static Drawable getCompatToolbarOverlay(Activity activity) {
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) return null;
|
2015-04-17 09:17:22 +02:00
|
|
|
final Window window = activity.getWindow();
|
|
|
|
final View view = window.findViewById(android.support.v7.appcompat.R.id.decor_content_parent);
|
|
|
|
if (!(view instanceof ActionBarOverlayLayout)) {
|
|
|
|
final View contentLayout = window.findViewById(android.support.v7.appcompat.R.id.action_bar_activity_content);
|
|
|
|
if (contentLayout instanceof ContentFrameLayout) {
|
|
|
|
return ((ContentFrameLayout) contentLayout).getForeground();
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
2015-04-15 13:14:47 +02:00
|
|
|
try {
|
|
|
|
final Field field = ActionBarOverlayLayout.class.getDeclaredField("mWindowContentOverlay");
|
|
|
|
field.setAccessible(true);
|
|
|
|
return (Drawable) field.get(view);
|
|
|
|
} catch (Exception ignore) {
|
2015-04-13 18:34:10 +02:00
|
|
|
}
|
2015-04-15 13:14:47 +02:00
|
|
|
return null;
|
2015-04-13 18:34:10 +02:00
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static int getComposeThemeResource(final Context context) {
|
|
|
|
return getComposeThemeResource(getThemeNameOption(context));
|
|
|
|
}
|
2015-01-17 19:58:29 +01:00
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static int getComposeThemeResource(final String name) {
|
|
|
|
if (VALUE_THEME_NAME_DARK.equals(name)) return R.style.Theme_Twidere_Dark_Compose;
|
|
|
|
return R.style.Theme_Twidere_Light_Compose;
|
2015-03-19 17:19:57 +01:00
|
|
|
}
|
|
|
|
|
2015-05-02 19:39:06 +02:00
|
|
|
public static int getContrastForegroundColor(Context context, int theme, int color) {
|
|
|
|
final int[] colors = new int[2];
|
|
|
|
getDarkLightForegroundColors(context, theme, colors);
|
2015-04-30 11:55:03 +02:00
|
|
|
if (isDarkTheme(theme) || TwidereColorUtils.getYIQLuminance(color) <= ACCENT_COLOR_THRESHOLD) {
|
2015-04-17 09:17:22 +02:00
|
|
|
//return light text color
|
2015-05-02 19:39:06 +02:00
|
|
|
return colors[1];
|
2015-04-17 09:17:22 +02:00
|
|
|
}
|
|
|
|
//return dark text color
|
2015-05-02 19:39:06 +02:00
|
|
|
return colors[0];
|
2015-04-17 09:17:22 +02:00
|
|
|
}
|
|
|
|
|
2015-05-02 14:55:16 +02:00
|
|
|
public static int getContrastActionBarItemColor(Context context) {
|
2015-05-02 19:39:06 +02:00
|
|
|
return getColorFromAttribute(context, android.R.attr.colorForeground, 0);
|
2015-04-17 09:17:22 +02:00
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static int getDialogThemeResource(final Context context) {
|
|
|
|
return getDialogThemeResource(getThemeNameOption(context));
|
2015-01-17 19:58:29 +01:00
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static int getDialogThemeResource(final String name) {
|
|
|
|
if (VALUE_THEME_NAME_DARK.equals(name)) return R.style.Theme_Twidere_Dark_Dialog;
|
|
|
|
return R.style.Theme_Twidere_Light_Dialog;
|
2014-07-27 14:58:15 +02:00
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static Context getDialogThemedContext(final Context context) {
|
|
|
|
return new ContextThemeWrapper(context, getDialogThemeResource(context));
|
2014-07-27 14:58:15 +02:00
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static int getDialogWhenLargeThemeResource(final Context context) {
|
|
|
|
return getDialogWhenLargeThemeResource(getThemeNameOption(context));
|
|
|
|
}
|
2015-01-17 19:58:29 +01:00
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static int getDialogWhenLargeThemeResource(final String name) {
|
|
|
|
if (VALUE_THEME_NAME_DARK.equals(name)) {
|
2015-04-27 14:25:26 +02:00
|
|
|
return R.style.Theme_Twidere_Dark_DialogWhenLarge_NoActionBar;
|
2015-01-17 19:58:29 +01:00
|
|
|
}
|
2015-04-27 14:25:26 +02:00
|
|
|
return R.style.Theme_Twidere_Light_DialogWhenLarge_NoActionBar;
|
2015-01-17 19:58:29 +01:00
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static int getDrawerThemeResource(final Context context) {
|
2015-04-27 14:25:26 +02:00
|
|
|
return getDrawerThemeResource(getNoActionBarThemeResource(context));
|
2014-11-01 17:57:31 +01:00
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static int getDrawerThemeResource(final int themeRes) {
|
|
|
|
return R.style.Theme_Twidere_Drawer_Dark;
|
2014-10-29 07:48:07 +01:00
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static Drawable getImageHighlightDrawable(final Context context) {
|
|
|
|
final Drawable d = getSelectableItemBackgroundDrawable(context);
|
|
|
|
if (d != null) {
|
|
|
|
d.setAlpha(0x80);
|
2014-10-25 12:45:50 +02:00
|
|
|
}
|
2015-04-15 13:14:47 +02:00
|
|
|
return d;
|
2014-10-25 12:45:50 +02:00
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static int getNoDisplayThemeResource(final Context context) {
|
|
|
|
if (context == null) return R.style.Theme_Twidere_Dark_NoDisplay;
|
|
|
|
final SharedPreferencesWrapper pref = getSharedPreferencesWrapper(context);
|
|
|
|
final String theme = pref.getString(KEY_THEME, VALUE_THEME_NAME_TWIDERE);
|
|
|
|
if (VALUE_THEME_NAME_DARK.equals(theme)) return R.style.Theme_Twidere_Dark_NoDisplay;
|
|
|
|
return R.style.Theme_Twidere_Light_NoDisplay;
|
2014-12-24 05:39:21 +01:00
|
|
|
}
|
|
|
|
|
2015-01-08 10:13:20 +01:00
|
|
|
public static int getOptimalLinkColor(int linkColor, int color) {
|
|
|
|
final int[] yiq = new int[3];
|
2015-04-22 10:36:56 +02:00
|
|
|
TwidereColorUtils.colorToYIQ(color, yiq);
|
2015-01-08 10:13:20 +01:00
|
|
|
final int y = yiq[0];
|
2015-04-22 10:36:56 +02:00
|
|
|
TwidereColorUtils.colorToYIQ(linkColor, yiq);
|
2015-04-30 11:55:03 +02:00
|
|
|
if (y < 32 && yiq[0] <= ACCENT_COLOR_THRESHOLD) {
|
2015-01-08 10:13:20 +01:00
|
|
|
return linkColor;
|
2015-04-26 15:46:23 +02:00
|
|
|
} else if (y > ACCENT_COLOR_THRESHOLD && yiq[0] > 32) {
|
2015-01-08 10:13:20 +01:00
|
|
|
return linkColor;
|
|
|
|
}
|
|
|
|
yiq[0] = yiq[0] + (y - yiq[0]) / 2;
|
2015-04-22 10:36:56 +02:00
|
|
|
return TwidereColorUtils.YIQToColor(Color.alpha(linkColor), yiq);
|
2015-01-08 10:13:20 +01:00
|
|
|
}
|
|
|
|
|
2015-01-10 16:17:02 +01:00
|
|
|
public static int getQuickSearchBarThemeResource(final Context context) {
|
|
|
|
return getQuickSearchBarThemeResource(getThemeNameOption(context));
|
2015-01-06 16:46:07 +01:00
|
|
|
}
|
|
|
|
|
2015-01-10 16:17:02 +01:00
|
|
|
public static int getQuickSearchBarThemeResource(final String name) {
|
|
|
|
if (VALUE_THEME_NAME_DARK.equals(name)) return R.style.Theme_Twidere_Dark_QuickSearchBar;
|
|
|
|
return R.style.Theme_Twidere_Light_QuickSearchBar;
|
2015-01-06 16:46:07 +01:00
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static Resources getResources(final Context context) {
|
|
|
|
return context.getResources();
|
2014-07-27 14:58:15 +02:00
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static Drawable getSelectableItemBackgroundDrawable(final Context context) {
|
|
|
|
final TypedArray a = context.obtainStyledAttributes(new int[]{android.R.attr.selectableItemBackground});
|
2015-04-01 12:28:26 +02:00
|
|
|
try {
|
2015-04-15 13:14:47 +02:00
|
|
|
return a.getDrawable(0);
|
2015-04-01 12:28:26 +02:00
|
|
|
} finally {
|
|
|
|
a.recycle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static float getSupportActionBarElevation(final Context context) {
|
2015-04-14 17:38:50 +02:00
|
|
|
@SuppressWarnings("ConstantConditions")
|
2015-04-15 13:14:47 +02:00
|
|
|
final TypedArray a = context.obtainStyledAttributes(null, new int[]{R.attr.elevation}, R.attr.actionBarStyle, 0);
|
2015-04-01 12:28:26 +02:00
|
|
|
try {
|
|
|
|
return a.getDimension(0, 0);
|
|
|
|
} finally {
|
|
|
|
a.recycle();
|
|
|
|
}
|
|
|
|
}
|
2014-07-27 14:58:15 +02:00
|
|
|
|
2015-04-30 11:55:03 +02:00
|
|
|
public static int getColorFromAttribute(Context context, int attr, int def) {
|
|
|
|
final TypedValue outValue = new TypedValue();
|
|
|
|
if (!context.getTheme().resolveAttribute(attr, outValue, true))
|
|
|
|
return def;
|
|
|
|
if (outValue.type == TypedValue.TYPE_REFERENCE)
|
|
|
|
return context.getResources().getColor(attr);
|
|
|
|
return outValue.data;
|
|
|
|
}
|
|
|
|
|
2015-05-17 12:14:29 +02:00
|
|
|
|
|
|
|
public static int getColorFromAttribute(Context context, int themeId, int attr, int def) {
|
|
|
|
final TypedValue outValue = new TypedValue();
|
|
|
|
final Resources.Theme theme = context.getResources().newTheme();
|
|
|
|
theme.applyStyle(themeId, true);
|
|
|
|
if (!theme.resolveAttribute(attr, outValue, true))
|
|
|
|
return def;
|
|
|
|
if (outValue.type == TypedValue.TYPE_REFERENCE)
|
|
|
|
return context.getResources().getColor(attr);
|
|
|
|
return outValue.data;
|
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static int getTextColorPrimary(final Context context) {
|
2015-04-26 12:55:41 +02:00
|
|
|
final TypedArray a = context.obtainStyledAttributes(ATTRS_TEXT_COLOR_PRIMARY);
|
|
|
|
try {
|
|
|
|
return a.getColor(0, Color.TRANSPARENT);
|
|
|
|
} finally {
|
|
|
|
a.recycle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-26 15:46:23 +02:00
|
|
|
public static void getTextColorPrimaryAndInverse(final Context context, int[] colors) {
|
|
|
|
final TypedArray a = context.obtainStyledAttributes(ATTRS_TEXT_COLOR_PRIMARY_AND_INVERSE);
|
|
|
|
try {
|
|
|
|
colors[0] = a.getColor(0, Color.TRANSPARENT);
|
|
|
|
colors[1] = a.getColor(1, Color.TRANSPARENT);
|
|
|
|
} finally {
|
|
|
|
a.recycle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void getDarkLightForegroundColors(final Context context, int themeRes, int[] colors) {
|
|
|
|
final TypedArray a = context.obtainStyledAttributes(ATTRS_COLOR_FOREGROUND_AND_INVERSE);
|
|
|
|
try {
|
|
|
|
if (isDarkTheme(themeRes)) {
|
|
|
|
colors[0] = a.getColor(1, Color.WHITE);
|
|
|
|
colors[1] = a.getColor(0, Color.BLACK);
|
|
|
|
} else {
|
|
|
|
colors[0] = a.getColor(0, Color.WHITE);
|
|
|
|
colors[1] = a.getColor(1, Color.BLACK);
|
|
|
|
}
|
|
|
|
} finally {
|
|
|
|
a.recycle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void getColorForegroundAndInverse(final Context context, int[] colors) {
|
|
|
|
final TypedArray a = context.obtainStyledAttributes(ATTRS_COLOR_FOREGROUND_AND_INVERSE);
|
|
|
|
try {
|
|
|
|
colors[0] = a.getColor(0, Color.WHITE);
|
|
|
|
colors[1] = a.getColor(1, Color.BLACK);
|
|
|
|
} finally {
|
|
|
|
a.recycle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static int getThemeBackgroundColor(final Context context) {
|
|
|
|
final TypedArray a = context.obtainStyledAttributes(new int[]{android.R.attr.colorBackground});
|
2014-07-27 14:58:15 +02:00
|
|
|
try {
|
2015-04-15 13:14:47 +02:00
|
|
|
return a.getColor(0, 0);
|
2014-07-27 14:58:15 +02:00
|
|
|
} finally {
|
|
|
|
a.recycle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static int getThemeBackgroundColor(final Context context, int themeRes) {
|
|
|
|
if (themeRes == 0) {
|
|
|
|
return getThemeBackgroundColor(context);
|
2014-07-27 14:58:15 +02:00
|
|
|
}
|
2015-04-14 17:38:50 +02:00
|
|
|
@SuppressWarnings("ConstantConditions")
|
2015-04-15 13:14:47 +02:00
|
|
|
final TypedArray a = context.obtainStyledAttributes(null, new int[]{android.R.attr.colorBackground},
|
|
|
|
0, themeRes);
|
2014-07-27 14:58:15 +02:00
|
|
|
try {
|
2015-04-15 13:14:47 +02:00
|
|
|
return a.getColor(0, 0);
|
2014-07-27 14:58:15 +02:00
|
|
|
} finally {
|
|
|
|
a.recycle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String getThemeBackgroundOption(final Context context) {
|
|
|
|
if (context == null) return VALUE_THEME_BACKGROUND_DEFAULT;
|
2014-08-07 19:58:42 +02:00
|
|
|
final SharedPreferencesWrapper pref = getSharedPreferencesWrapper(context);
|
2014-07-27 14:58:15 +02:00
|
|
|
return pref.getString(KEY_THEME_BACKGROUND, VALUE_THEME_BACKGROUND_DEFAULT);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int getThemeColor(final Context context) {
|
2015-04-14 18:05:02 +02:00
|
|
|
final TypedArray a = context.obtainStyledAttributes(new int[]{android.R.attr.colorActivatedHighlight});
|
2014-07-27 14:58:15 +02:00
|
|
|
try {
|
2015-04-14 18:05:02 +02:00
|
|
|
final Resources resources = context.getResources();
|
|
|
|
return a.getColor(0, resources.getColor(R.color.material_light_blue));
|
2014-07-27 14:58:15 +02:00
|
|
|
} finally {
|
|
|
|
a.recycle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static int getThemeColor(Context context, int themeResourceId) {
|
|
|
|
final Context appContext = context.getApplicationContext();
|
|
|
|
final Resources res = appContext.getResources();
|
|
|
|
@SuppressWarnings("ConstantConditions")
|
|
|
|
final TypedArray a = appContext.obtainStyledAttributes(null,
|
|
|
|
new int[]{android.R.attr.colorActivatedHighlight}, 0, themeResourceId);
|
|
|
|
try {
|
|
|
|
return a.getColor(0, res.getColor(R.color.material_light_blue));
|
|
|
|
} finally {
|
|
|
|
a.recycle();
|
|
|
|
}
|
2014-07-27 14:58:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static String getThemeFontFamily(final Context context) {
|
|
|
|
if (context == null) return VALUE_THEME_FONT_FAMILY_REGULAR;
|
2014-08-07 19:58:42 +02:00
|
|
|
final SharedPreferencesWrapper pref = getSharedPreferencesWrapper(context);
|
2014-07-27 14:58:15 +02:00
|
|
|
final String fontFamily = pref.getString(KEY_THEME_FONT_FAMILY, VALUE_THEME_FONT_FAMILY_REGULAR);
|
|
|
|
if (!TextUtils.isEmpty(fontFamily)) return fontFamily;
|
|
|
|
return VALUE_THEME_FONT_FAMILY_REGULAR;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int getThemeForegroundColor(final Context context) {
|
2014-11-01 17:57:31 +01:00
|
|
|
return getThemeForegroundColor(context, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int getThemeForegroundColor(final Context context, int theme) {
|
2015-05-03 16:43:05 +02:00
|
|
|
@SuppressWarnings("ConstantConditions")
|
|
|
|
final TypedArray a = context.obtainStyledAttributes(null, new int[]{android.R.attr.colorForeground}, 0, theme);
|
2014-07-27 14:58:15 +02:00
|
|
|
try {
|
2014-11-01 17:57:31 +01:00
|
|
|
return a.getColor(0, 0);
|
2014-07-27 14:58:15 +02:00
|
|
|
} finally {
|
|
|
|
a.recycle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String getThemeNameOption(final Context context) {
|
|
|
|
if (context == null) return VALUE_THEME_NAME_TWIDERE;
|
2014-08-07 19:58:42 +02:00
|
|
|
final SharedPreferencesWrapper pref = getSharedPreferencesWrapper(context);
|
|
|
|
return pref.getString(KEY_THEME, VALUE_THEME_NAME_TWIDERE);
|
2014-07-27 14:58:15 +02:00
|
|
|
}
|
|
|
|
|
2015-04-27 19:57:39 +02:00
|
|
|
public static int getThemeResource(final int otherTheme) {
|
|
|
|
if (isDarkTheme(otherTheme)) {
|
|
|
|
return R.style.Theme_Twidere_Dark;
|
|
|
|
}
|
|
|
|
return R.style.Theme_Twidere_Light;
|
|
|
|
}
|
|
|
|
|
2015-04-27 14:25:26 +02:00
|
|
|
public static int getNoActionBarThemeResource(final Context context) {
|
|
|
|
return getNoActionBarThemeResource(getThemeNameOption(context));
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int getNoActionBarThemeResource(final String name) {
|
|
|
|
if (VALUE_THEME_NAME_DARK.equals(name)) {
|
|
|
|
return R.style.Theme_Twidere_Dark_NoActionBar;
|
|
|
|
}
|
|
|
|
return R.style.Theme_Twidere_Light_NoActionBar;
|
|
|
|
}
|
|
|
|
|
2014-07-27 14:58:15 +02:00
|
|
|
public static int getTitleTextAppearance(final Context context) {
|
2015-04-14 17:38:50 +02:00
|
|
|
@SuppressWarnings("ConstantConditions")
|
2014-07-27 14:58:15 +02:00
|
|
|
final TypedArray a = context.obtainStyledAttributes(null, new int[]{android.R.attr.titleTextStyle},
|
|
|
|
android.R.attr.actionBarStyle, android.R.style.Widget_Holo_ActionBar);
|
|
|
|
final int textAppearance = a.getResourceId(0, android.R.style.TextAppearance_Holo);
|
|
|
|
a.recycle();
|
|
|
|
return textAppearance;
|
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static int getUserAccentColor(final Context context) {
|
|
|
|
if (context == null) return Color.TRANSPARENT;
|
|
|
|
final SharedPreferencesWrapper pref = getSharedPreferencesWrapper(context);
|
|
|
|
final Resources res = context.getResources();
|
|
|
|
final int def = res.getColor(R.color.branding_color);
|
|
|
|
return pref.getInt(KEY_THEME_COLOR, def);
|
|
|
|
}
|
|
|
|
|
2015-04-30 12:37:29 +02:00
|
|
|
public static int getOptimalAccentColor(final Context context, boolean isActionBarContext, int themeResId) {
|
|
|
|
final int userAccentColor = getUserAccentColor(context);
|
|
|
|
final int backgroundColorApprox;
|
|
|
|
final boolean isDarkTheme = isDarkTheme(themeResId);
|
|
|
|
if (!isActionBarContext) {
|
|
|
|
backgroundColorApprox = isDarkTheme ? Color.BLACK : Color.WHITE;
|
|
|
|
} else if (isDarkTheme) {
|
|
|
|
// View context is derived from ActionBar but is currently dark theme, so we should show
|
|
|
|
// light
|
|
|
|
backgroundColorApprox = Color.BLACK;
|
|
|
|
} else {
|
|
|
|
// View context is derived from ActionBar and it's light theme, so we use contrast color
|
|
|
|
backgroundColorApprox = Color.WHITE;
|
|
|
|
}
|
|
|
|
if (Math.abs(TwidereColorUtils.getYIQContrast(backgroundColorApprox, userAccentColor)) > 64)
|
|
|
|
return userAccentColor;
|
|
|
|
return getColorFromAttribute(context, R.attr.colorAccent, context.getResources().getColor(R.color.branding_color));
|
|
|
|
}
|
|
|
|
|
2014-07-27 14:58:15 +02:00
|
|
|
public static int getUserHighlightColor(final Context context) {
|
|
|
|
final int color = getUserLinkTextColor(context);
|
|
|
|
final int red = Color.red(color), green = Color.green(color), blue = Color.blue(color);
|
|
|
|
return Color.argb(0x66, red, green, blue);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int getUserLinkTextColor(final Context context) {
|
|
|
|
if (context == null) return new TextPaint().linkColor;
|
2014-10-29 07:48:07 +01:00
|
|
|
final int themeColor = getUserAccentColor(context);
|
2014-07-27 14:58:15 +02:00
|
|
|
final float[] hsv = new float[3];
|
|
|
|
Color.colorToHSV(themeColor, hsv);
|
|
|
|
if (isDarkTheme(context)) {
|
|
|
|
hsv[2] = MathUtils.clamp(hsv[2], 1, 0.5f);
|
|
|
|
} else {
|
|
|
|
hsv[2] = MathUtils.clamp(hsv[2], 0.1f, 0.75f);
|
|
|
|
}
|
|
|
|
return Color.HSVToColor(hsv);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int getUserThemeBackgroundAlpha(final Context context) {
|
|
|
|
if (context == null) return DEFAULT_THEME_BACKGROUND_ALPHA;
|
2014-08-07 19:58:42 +02:00
|
|
|
final SharedPreferencesWrapper pref = getSharedPreferencesWrapper(context);
|
2015-05-17 17:16:54 +02:00
|
|
|
return MathUtils.clamp(pref.getInt(KEY_THEME_BACKGROUND_ALPHA, DEFAULT_THEME_BACKGROUND_ALPHA),
|
|
|
|
ThemeBackgroundPreference.MIN_ALPHA, ThemeBackgroundPreference.MAX_ALPHA);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int getActionBarAlpha(final int alpha) {
|
|
|
|
return MathUtils.clamp(alpha * 2, ThemeBackgroundPreference.MIN_ALPHA,
|
|
|
|
ThemeBackgroundPreference.MAX_ALPHA);
|
2014-07-27 14:58:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static Typeface getUserTypeface(final Context context, final Typeface defTypeface) {
|
|
|
|
if (context == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
|
|
|
|
return Typeface.DEFAULT;
|
|
|
|
final int fontStyle = defTypeface != null ? defTypeface.getStyle() : Typeface.NORMAL;
|
|
|
|
final String fontFamily = getThemeFontFamily(context);
|
|
|
|
final Typeface tf = Typeface.create(fontFamily, fontStyle);
|
|
|
|
if (tf != null) return tf;
|
|
|
|
return Typeface.create(Typeface.DEFAULT, fontStyle);
|
|
|
|
}
|
|
|
|
|
2015-04-24 11:19:26 +02:00
|
|
|
public static Typeface getUserTypeface(final Context context, final String fontFamily, final Typeface defTypeface) {
|
|
|
|
if (context == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
|
|
|
|
return Typeface.DEFAULT;
|
|
|
|
final int fontStyle = defTypeface != null ? defTypeface.getStyle() : Typeface.NORMAL;
|
|
|
|
final Typeface tf = Typeface.create(fontFamily, fontStyle);
|
|
|
|
if (tf != null) return tf;
|
|
|
|
return Typeface.create(Typeface.DEFAULT, fontStyle);
|
|
|
|
}
|
|
|
|
|
2014-07-27 14:58:15 +02:00
|
|
|
public static int getViewerThemeResource(final Context context) {
|
2015-01-23 17:09:03 +01:00
|
|
|
return R.style.Theme_Twidere_Viewer;
|
2014-07-27 14:58:15 +02:00
|
|
|
}
|
|
|
|
|
2015-04-17 09:17:22 +02:00
|
|
|
public static Drawable getWindowBackground(final Context context) {
|
|
|
|
final TypedArray a = context.obtainStyledAttributes(new int[]{android.R.attr.windowBackground});
|
|
|
|
try {
|
|
|
|
return a.getDrawable(0);
|
|
|
|
} finally {
|
|
|
|
a.recycle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static Drawable getWindowBackgroundFromTheme(final Context context, int theme) {
|
2015-04-14 17:38:50 +02:00
|
|
|
@SuppressWarnings("ConstantConditions")
|
|
|
|
final TypedArray a = context.obtainStyledAttributes(null, new int[]{android.R.attr.windowBackground}, 0, theme);
|
2015-04-15 13:14:47 +02:00
|
|
|
try {
|
|
|
|
return a.getDrawable(0);
|
|
|
|
} finally {
|
|
|
|
a.recycle();
|
2014-07-27 14:58:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-03 16:43:05 +02:00
|
|
|
public static Drawable getWindowBackgroundFromThemeApplyAlpha(final Context context, final int theme, final int alpha) {
|
|
|
|
@SuppressWarnings("ConstantConditions")
|
|
|
|
final TypedArray a = context.obtainStyledAttributes(null, new int[]{android.R.attr.windowBackground}, 0, theme);
|
|
|
|
final Drawable d = a.getDrawable(0);
|
|
|
|
a.recycle();
|
|
|
|
if (d != null) {
|
2015-05-17 17:16:54 +02:00
|
|
|
d.setAlpha(MathUtils.clamp(alpha, ThemeBackgroundPreference.MIN_ALPHA,
|
|
|
|
ThemeBackgroundPreference.MAX_ALPHA));
|
2015-05-03 16:43:05 +02:00
|
|
|
}
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
2014-07-27 14:58:15 +02:00
|
|
|
public static Drawable getWindowContentOverlay(final Context context) {
|
|
|
|
final TypedArray a = context.obtainStyledAttributes(new int[]{android.R.attr.windowContentOverlay});
|
2015-04-15 13:14:47 +02:00
|
|
|
try {
|
|
|
|
return a.getDrawable(0);
|
|
|
|
} finally {
|
|
|
|
a.recycle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-27 14:25:26 +02:00
|
|
|
public static Drawable getWindowContentOverlay(final Context context, int themeRes) {
|
|
|
|
@SuppressWarnings("ConstantConditions")
|
|
|
|
final TypedArray a = context.obtainStyledAttributes(null, new int[]{android.R.attr.windowContentOverlay}, 0, themeRes);
|
|
|
|
try {
|
|
|
|
return a.getDrawable(0);
|
|
|
|
} finally {
|
|
|
|
a.recycle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-27 19:57:39 +02:00
|
|
|
public static Drawable getNormalWindowContentOverlay(final Context context, int themeRes) {
|
|
|
|
final int normalThemeResId = ThemeUtils.getThemeResource(themeRes);
|
|
|
|
return getWindowContentOverlay(context, normalThemeResId);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void initPagerIndicatorAsActionBarTab(FragmentActivity activity, TabPagerIndicator indicator, @Nullable View pagerOverlay) {
|
2015-04-15 13:14:47 +02:00
|
|
|
final float supportActionBarElevation = getSupportActionBarElevation(activity);
|
|
|
|
ViewCompat.setElevation(indicator, supportActionBarElevation);
|
|
|
|
if (!(activity instanceof IThemedActivity)) return;
|
|
|
|
final int themeRes = ((IThemedActivity) activity).getCurrentThemeResourceId();
|
|
|
|
final int themeColor = ((IThemedActivity) activity).getCurrentThemeColor();
|
2015-05-12 17:47:52 +02:00
|
|
|
final String backgroundOption = ((IThemedActivity) activity).getCurrentThemeBackgroundOption();
|
2015-04-26 15:46:23 +02:00
|
|
|
final int colorDark, colorLight;
|
|
|
|
final int[] textColors = new int[2];
|
|
|
|
getTextColorPrimaryAndInverse(activity, textColors);
|
|
|
|
if (isDarkTheme(themeRes)) {
|
|
|
|
colorDark = textColors[1];
|
|
|
|
colorLight = textColors[0];
|
|
|
|
} else {
|
|
|
|
colorDark = textColors[0];
|
|
|
|
colorLight = textColors[1];
|
|
|
|
}
|
2015-04-27 19:57:39 +02:00
|
|
|
final int contrastColor = TwidereColorUtils.getContrastYIQ(themeColor, ACCENT_COLOR_THRESHOLD,
|
|
|
|
colorDark, colorLight);
|
2015-05-12 17:47:52 +02:00
|
|
|
ViewSupport.setBackground(indicator, getActionBarStackedBackground(activity, themeRes, themeColor, backgroundOption, true));
|
2015-04-15 13:14:47 +02:00
|
|
|
if (isDarkTheme(themeRes)) {
|
|
|
|
final int foregroundColor = getThemeForegroundColor(activity);
|
|
|
|
indicator.setIconColor(foregroundColor);
|
|
|
|
indicator.setLabelColor(foregroundColor);
|
|
|
|
indicator.setStripColor(themeColor);
|
|
|
|
} else {
|
|
|
|
indicator.setIconColor(contrastColor);
|
|
|
|
indicator.setLabelColor(contrastColor);
|
|
|
|
indicator.setStripColor(contrastColor);
|
|
|
|
}
|
|
|
|
indicator.updateAppearance();
|
2015-04-27 19:57:39 +02:00
|
|
|
if (pagerOverlay != null) {
|
|
|
|
ViewSupport.setBackground(pagerOverlay, getNormalWindowContentOverlay(activity, themeRes));
|
|
|
|
}
|
2015-04-15 13:14:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean isColoredActionBar(int themeRes) {
|
|
|
|
return !isDarkTheme(themeRes);
|
2014-07-27 14:58:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean isDarkTheme(final Context context) {
|
2015-04-27 14:25:26 +02:00
|
|
|
return isDarkTheme(getNoActionBarThemeResource(context));
|
2014-07-27 14:58:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean isDarkTheme(final int themeRes) {
|
|
|
|
switch (themeRes) {
|
|
|
|
case R.style.Theme_Twidere_Dark:
|
2015-04-27 14:25:26 +02:00
|
|
|
case R.style.Theme_Twidere_Dark_NoActionBar:
|
2014-07-27 14:58:15 +02:00
|
|
|
case R.style.Theme_Twidere_Dark_Dialog:
|
2015-04-27 14:25:26 +02:00
|
|
|
case R.style.Theme_Twidere_Dark_DialogWhenLarge_NoActionBar:
|
2014-07-27 14:58:15 +02:00
|
|
|
case R.style.Theme_Twidere_Dark_Compose:
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-04-22 10:36:56 +02:00
|
|
|
public static boolean isSolidBackground(final String option) {
|
|
|
|
return VALUE_THEME_BACKGROUND_SOLID.equals(option);
|
|
|
|
}
|
|
|
|
|
2014-07-27 14:58:15 +02:00
|
|
|
public static boolean isTransparentBackground(final Context context) {
|
2015-04-14 17:38:50 +02:00
|
|
|
return isTransparentBackground(getThemeBackgroundOption(context));
|
2014-07-27 14:58:15 +02:00
|
|
|
}
|
|
|
|
|
2015-04-14 17:38:50 +02:00
|
|
|
public static boolean isTransparentBackground(final String option) {
|
|
|
|
return VALUE_THEME_BACKGROUND_TRANSPARENT.equals(option);
|
2014-07-27 14:58:15 +02:00
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static boolean isWindowFloating(Context context, int theme) {
|
|
|
|
final TypedArray a;
|
|
|
|
if (theme != 0) {
|
|
|
|
//noinspection ConstantConditions
|
|
|
|
a = context.obtainStyledAttributes(null, new int[]{android.R.attr.windowIsFloating}, 0, theme);
|
|
|
|
} else {
|
|
|
|
a = context.obtainStyledAttributes(new int[]{android.R.attr.windowIsFloating});
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
return a.getBoolean(0, false);
|
|
|
|
} finally {
|
|
|
|
a.recycle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-27 14:58:15 +02:00
|
|
|
public static void overrideActivityCloseAnimation(final Activity activity) {
|
|
|
|
TypedArray a = activity.obtainStyledAttributes(new int[]{android.R.attr.windowAnimationStyle});
|
|
|
|
final int windowAnimationStyleResId = a.getResourceId(0, 0);
|
|
|
|
a.recycle();
|
|
|
|
// Now retrieve the resource ids of the actual animations used in the
|
|
|
|
// animation style pointed to by
|
|
|
|
// the window animation resource id.
|
|
|
|
a = activity.obtainStyledAttributes(windowAnimationStyleResId, ANIM_CLOSE_STYLE_ATTRS);
|
|
|
|
final int activityCloseEnterAnimation = a.getResourceId(0, 0);
|
|
|
|
final int activityCloseExitAnimation = a.getResourceId(1, 0);
|
|
|
|
a.recycle();
|
|
|
|
activity.overridePendingTransition(activityCloseEnterAnimation, activityCloseExitAnimation);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void overrideActivityOpenAnimation(final Activity activity) {
|
|
|
|
|
|
|
|
TypedArray a = activity.obtainStyledAttributes(new int[]{android.R.attr.windowAnimationStyle});
|
|
|
|
final int windowAnimationStyleResId = a.getResourceId(0, 0);
|
|
|
|
a.recycle();
|
|
|
|
// Now retrieve the resource ids of the actual animations used in the
|
|
|
|
// animation style pointed to by
|
|
|
|
// the window animation resource id.
|
|
|
|
a = activity.obtainStyledAttributes(windowAnimationStyleResId, ANIM_OPEN_STYLE_ATTRS);
|
|
|
|
final int activityOpenEnterAnimation = a.getResourceId(0, 0);
|
|
|
|
final int activityOpenExitAnimation = a.getResourceId(1, 0);
|
|
|
|
a.recycle();
|
|
|
|
activity.overridePendingTransition(activityOpenEnterAnimation, activityOpenExitAnimation);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void overrideNormalActivityCloseAnimation(final Activity activity) {
|
2015-04-14 17:38:50 +02:00
|
|
|
@SuppressWarnings("ConstantConditions")
|
2014-07-28 12:42:48 +02:00
|
|
|
final TypedArray a = activity.obtainStyledAttributes(null, ANIM_CLOSE_STYLE_ATTRS,
|
|
|
|
0, android.R.style.Animation_Activity);
|
2014-07-27 14:58:15 +02:00
|
|
|
final int activityCloseEnterAnimation = a.getResourceId(0, 0);
|
|
|
|
final int activityCloseExitAnimation = a.getResourceId(1, 0);
|
|
|
|
a.recycle();
|
|
|
|
activity.overridePendingTransition(activityCloseEnterAnimation, activityCloseExitAnimation);
|
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static void resetCheatSheet(ActionMenuView menuView) {
|
|
|
|
final OnLongClickListener listener = new OnLongClickListener() {
|
|
|
|
@Override
|
|
|
|
public boolean onLongClick(View v) {
|
|
|
|
if (((ActionMenuItemView) v).hasText()) return false;
|
|
|
|
final MenuItem menuItem = ((ActionMenuItemView) v).getItemData();
|
|
|
|
Utils.showMenuItemToast(v, menuItem.getTitle(), true);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
for (int i = 0, j = menuView.getChildCount(); i < j; i++) {
|
|
|
|
final View child = menuView.getChildAt(i);
|
|
|
|
if (!(child instanceof ActionMenuItemView)) continue;
|
|
|
|
final ActionMenuItemView itemView = (ActionMenuItemView) child;
|
|
|
|
final MenuItem menuItem = itemView.getItemData();
|
|
|
|
if (menuItem.hasSubMenu()) continue;
|
|
|
|
itemView.setOnLongClickListener(listener);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void setActionBarOverflowColor(Toolbar toolbar, int itemColor) {
|
|
|
|
if (toolbar == null) return;
|
2015-04-30 11:55:03 +02:00
|
|
|
if (toolbar instanceof TwidereToolbar) {
|
|
|
|
((TwidereToolbar) toolbar).setItemColor(itemColor);
|
|
|
|
}
|
2015-04-27 14:25:26 +02:00
|
|
|
final ActionMenuView actionMenuView = ViewSupport.findViewByType(toolbar, ActionMenuView.class);
|
2015-04-15 13:14:47 +02:00
|
|
|
if (actionMenuView == null) return;
|
|
|
|
View overflowView = null;
|
|
|
|
for (int i = 0, j = actionMenuView.getChildCount(); i < j; i++) {
|
|
|
|
final View child = actionMenuView.getChildAt(i);
|
|
|
|
final ActionMenuView.LayoutParams lp = (ActionMenuView.LayoutParams) child.getLayoutParams();
|
|
|
|
if (lp.isOverflowButton) {
|
|
|
|
overflowView = child;
|
|
|
|
break;
|
|
|
|
}
|
2014-07-27 14:58:15 +02:00
|
|
|
}
|
2015-04-15 13:14:47 +02:00
|
|
|
if (!(overflowView instanceof ImageView)) return;
|
2015-04-27 20:36:34 +02:00
|
|
|
((ImageView) overflowView).setColorFilter(itemColor, Mode.SRC_ATOP);
|
2014-07-27 14:58:15 +02:00
|
|
|
}
|
|
|
|
|
2015-04-30 11:55:03 +02:00
|
|
|
public static void setActionBarMenuItemsColor(Toolbar toolbar, int itemColor) {
|
|
|
|
if (toolbar == null) return;
|
|
|
|
if (toolbar instanceof TwidereToolbar) {
|
|
|
|
((TwidereToolbar) toolbar).setItemColor(itemColor);
|
|
|
|
}
|
|
|
|
final ActionMenuView actionMenuView = ViewSupport.findViewByType(toolbar, ActionMenuView.class);
|
|
|
|
if (actionMenuView == null) return;
|
|
|
|
for (int i = 0, j = actionMenuView.getChildCount(); i < j; i++) {
|
|
|
|
final View child = actionMenuView.getChildAt(i);
|
|
|
|
if (child instanceof ActionMenuView.ActionMenuChildView && child instanceof ImageView) {
|
|
|
|
((ImageView) child).setColorFilter(itemColor, Mode.SRC_ATOP);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-28 09:18:20 +02:00
|
|
|
public static void setActionBarOverflowColor(ActionMenuPresenter presenter, int itemColor) {
|
|
|
|
if (presenter == null) return;
|
2015-04-28 18:54:42 +02:00
|
|
|
final View view = (View) Utils.findFieldOfTypes(presenter, ActionMenuPresenter.class,
|
|
|
|
ActionMenuView.ActionMenuChildView.class, View.class);
|
|
|
|
if (!(view instanceof ImageView)) return;
|
|
|
|
((ImageView) view).setColorFilter(itemColor, Mode.SRC_ATOP);
|
2015-04-28 09:18:20 +02:00
|
|
|
}
|
|
|
|
|
2015-04-17 04:54:48 +02:00
|
|
|
public static void setActionBarOverflowColor(ActionMenuView actionMenuView, int itemColor) {
|
|
|
|
if (actionMenuView == null) return;
|
|
|
|
View overflowView = null;
|
|
|
|
for (int i = 0, j = actionMenuView.getChildCount(); i < j; i++) {
|
|
|
|
final View child = actionMenuView.getChildAt(i);
|
|
|
|
final ActionMenuView.LayoutParams lp = (ActionMenuView.LayoutParams) child.getLayoutParams();
|
|
|
|
if (lp.isOverflowButton) {
|
|
|
|
overflowView = child;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!(overflowView instanceof ImageView)) return;
|
|
|
|
final Drawable drawable = ((ImageView) overflowView).getDrawable();
|
|
|
|
if (drawable == null) return;
|
|
|
|
drawable.setColorFilter(itemColor, Mode.SRC_ATOP);
|
|
|
|
}
|
|
|
|
|
2015-04-17 09:17:22 +02:00
|
|
|
public static void setCompatToolbarOverlay(Activity activity, Drawable overlay) {
|
2015-04-15 13:14:47 +02:00
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) return;
|
2015-04-17 09:17:22 +02:00
|
|
|
final Window window = activity.getWindow();
|
|
|
|
final View view = window.findViewById(android.support.v7.appcompat.R.id.decor_content_parent);
|
2015-04-26 15:46:23 +02:00
|
|
|
if (!(view instanceof ActionBarOverlayLayout)) return;
|
2014-08-07 19:58:42 +02:00
|
|
|
try {
|
2015-04-15 13:14:47 +02:00
|
|
|
final Field field = ActionBarOverlayLayout.class.getDeclaredField("mWindowContentOverlay");
|
|
|
|
field.setAccessible(true);
|
2015-04-17 09:17:22 +02:00
|
|
|
field.set(view, overlay);
|
2015-04-15 13:14:47 +02:00
|
|
|
} catch (Exception ignore) {
|
2014-08-07 19:58:42 +02:00
|
|
|
}
|
|
|
|
}
|
2014-10-29 07:48:07 +01:00
|
|
|
|
2015-04-26 15:46:23 +02:00
|
|
|
public static void setCompatContentViewOverlay(Activity activity, Drawable overlay) {
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) return;
|
|
|
|
final Window window = activity.getWindow();
|
|
|
|
View contentLayout = window.findViewById(android.support.v7.appcompat.R.id.action_bar_activity_content);
|
|
|
|
if (contentLayout == null) {
|
|
|
|
contentLayout = window.findViewById(android.R.id.content);
|
|
|
|
}
|
|
|
|
if (contentLayout instanceof ContentFrameLayout) {
|
|
|
|
((ContentFrameLayout) contentLayout).setForeground(overlay);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-27 14:25:26 +02:00
|
|
|
public static void setWindowOverlayViewOverlay(Activity activity, Drawable overlay) {
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) return;
|
|
|
|
final Window window = activity.getWindow();
|
|
|
|
final View windowOverlay = window.findViewById(R.id.window_overlay);
|
|
|
|
if (windowOverlay == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ViewSupport.setBackground(windowOverlay, overlay);
|
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static void setupDrawerBackground(Context context, View view) {
|
|
|
|
if (!(context instanceof IThemedActivity)) return;
|
|
|
|
final int themeRes = ((IThemedActivity) context).getCurrentThemeResourceId();
|
|
|
|
final int drawerThemeRes = getDrawerThemeResource(themeRes);
|
|
|
|
final String backgroundOption = ((IThemedActivity) context).getThemeBackgroundOption();
|
|
|
|
final int alpha = ((IThemedActivity) context).getCurrentThemeBackgroundAlpha();
|
2015-05-11 18:36:18 +02:00
|
|
|
final Drawable d;
|
|
|
|
if (isSolidBackground(backgroundOption)) {
|
|
|
|
d = new ColorDrawable(Color.BLACK);
|
|
|
|
} else {
|
|
|
|
d = getWindowBackgroundFromTheme(context, drawerThemeRes);
|
|
|
|
}
|
|
|
|
if (d == null) throw new NullPointerException();
|
|
|
|
if (isTransparentBackground(backgroundOption)) {
|
2015-04-15 13:14:47 +02:00
|
|
|
d.setAlpha(alpha);
|
|
|
|
}
|
2015-04-27 14:25:26 +02:00
|
|
|
ViewSupport.setBackground(view, d);
|
2014-10-29 07:48:07 +01:00
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static void wrapMenuIcon(@NonNull Menu menu, int itemColor, int subItemColor, int... excludeGroups) {
|
|
|
|
for (int i = 0, j = menu.size(); i < j; i++) {
|
|
|
|
final MenuItem item = menu.getItem(i);
|
|
|
|
wrapMenuItemIcon(item, itemColor, excludeGroups);
|
|
|
|
if (item.hasSubMenu()) {
|
|
|
|
wrapMenuIcon(item.getSubMenu(), subItemColor, subItemColor, excludeGroups);
|
|
|
|
}
|
|
|
|
}
|
2014-10-29 07:48:07 +01:00
|
|
|
}
|
2014-11-22 15:12:54 +01:00
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static void wrapMenuIcon(ActionMenuView view, int... excludeGroups) {
|
|
|
|
final Resources resources = view.getResources();
|
|
|
|
final int colorDark = resources.getColor(R.color.action_icon_dark);
|
|
|
|
final int colorLight = resources.getColor(R.color.action_icon_light);
|
|
|
|
wrapMenuIcon(view, colorDark, colorLight, excludeGroups);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void wrapMenuIcon(ActionMenuView view, int colorDark, int colorLight, int... excludeGroups) {
|
|
|
|
final int itemBackgroundColor = ThemeUtils.getThemeBackgroundColor(view.getContext());
|
|
|
|
final int popupItemBackgroundColor = ThemeUtils.getThemeBackgroundColor(view.getContext(), view.getPopupTheme());
|
2015-04-22 10:36:56 +02:00
|
|
|
final int itemColor = TwidereColorUtils.getContrastYIQ(itemBackgroundColor, colorDark, colorLight);
|
|
|
|
final int popupItemColor = TwidereColorUtils.getContrastYIQ(popupItemBackgroundColor, colorDark, colorLight);
|
2015-04-15 13:14:47 +02:00
|
|
|
final Menu menu = view.getMenu();
|
|
|
|
final int childCount = view.getChildCount();
|
|
|
|
for (int i = 0, j = menu.size(), k = 0; i < j; i++) {
|
|
|
|
final MenuItem item = menu.getItem(i);
|
|
|
|
wrapMenuItemIcon(item, itemColor, excludeGroups);
|
|
|
|
if (item.hasSubMenu()) {
|
2015-04-22 16:19:26 +02:00
|
|
|
wrapMenuIcon(item.getSubMenu(), popupItemColor, popupItemColor, excludeGroups);
|
2015-04-15 13:14:47 +02:00
|
|
|
}
|
|
|
|
if (item.isVisible()) {
|
|
|
|
k++;
|
2014-11-22 15:12:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-13 18:34:10 +02:00
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
public static void wrapMenuItemIcon(@NonNull MenuItem item, int itemColor, int... excludeGroups) {
|
|
|
|
if (ArrayUtils.contains(excludeGroups, item.getGroupId())) return;
|
|
|
|
final Drawable icon = item.getIcon();
|
|
|
|
if (icon == null) return;
|
|
|
|
if (icon instanceof ActionIconDrawable) {
|
|
|
|
((ActionIconDrawable) icon).setDefaultColor(itemColor);
|
|
|
|
item.setIcon(icon);
|
|
|
|
return;
|
2015-04-13 18:34:10 +02:00
|
|
|
}
|
2015-04-15 13:14:47 +02:00
|
|
|
icon.mutate();
|
|
|
|
final Drawable.Callback callback = icon.getCallback();
|
|
|
|
final ActionIconDrawable newIcon = new ActionIconDrawable(icon, itemColor);
|
|
|
|
newIcon.setCallback(callback);
|
|
|
|
item.setIcon(newIcon);
|
2015-04-13 18:34:10 +02:00
|
|
|
}
|
|
|
|
|
2015-04-17 04:54:48 +02:00
|
|
|
public static void wrapToolbarMenuIcon(@Nullable ActionMenuView view, int itemColor, int popupItemColor, int... excludeGroups) {
|
|
|
|
if (view == null) return;
|
2015-04-15 13:14:47 +02:00
|
|
|
final Menu menu = view.getMenu();
|
|
|
|
final int childCount = view.getChildCount();
|
|
|
|
for (int i = 0, j = menu.size(), k = 0; i < j; i++) {
|
|
|
|
final MenuItem item = menu.getItem(i);
|
|
|
|
wrapMenuItemIcon(item, itemColor, excludeGroups);
|
|
|
|
if (item.hasSubMenu()) {
|
2015-04-22 16:19:26 +02:00
|
|
|
wrapMenuIcon(item.getSubMenu(), popupItemColor, popupItemColor, excludeGroups);
|
2015-04-15 13:14:47 +02:00
|
|
|
}
|
|
|
|
if (item.isVisible()) {
|
|
|
|
k++;
|
|
|
|
}
|
2015-04-14 17:38:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-15 13:14:47 +02:00
|
|
|
@NonNull
|
|
|
|
private static SharedPreferencesWrapper getSharedPreferencesWrapper(Context context) {
|
|
|
|
final Context appContext = context.getApplicationContext();
|
|
|
|
return SharedPreferencesWrapper.getInstance(appContext, SHARED_PREFERENCES_NAME,
|
|
|
|
Context.MODE_PRIVATE);
|
|
|
|
}
|
|
|
|
|
2015-04-27 14:25:26 +02:00
|
|
|
public static int getActionBarHeight(Context context) {
|
|
|
|
final TypedValue tv = new TypedValue();
|
|
|
|
final Resources.Theme theme = context.getTheme();
|
|
|
|
final int attr = R.attr.actionBarSize;
|
|
|
|
if (theme.resolveAttribute(attr, tv, true)) {
|
|
|
|
return TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2015-04-27 20:36:34 +02:00
|
|
|
|
2015-04-28 06:47:57 +02:00
|
|
|
public static Context getActionBarThemedContext(Context base) {
|
|
|
|
final TypedValue outValue = new TypedValue();
|
|
|
|
final Resources.Theme baseTheme = base.getTheme();
|
|
|
|
baseTheme.resolveAttribute(android.support.v7.appcompat.R.attr.actionBarTheme, outValue, true);
|
|
|
|
|
|
|
|
if (outValue.resourceId != 0) {
|
|
|
|
final Resources.Theme actionBarTheme = base.getResources().newTheme();
|
|
|
|
actionBarTheme.setTo(baseTheme);
|
|
|
|
actionBarTheme.applyStyle(outValue.resourceId, true);
|
|
|
|
|
2015-05-03 16:43:05 +02:00
|
|
|
final ActionBarContextThemeWrapper actionBarContext = new ActionBarContextThemeWrapper(base, outValue.resourceId);
|
2015-04-28 06:47:57 +02:00
|
|
|
actionBarContext.getTheme().setTo(actionBarTheme);
|
|
|
|
return actionBarContext;
|
|
|
|
} else {
|
|
|
|
return base;
|
|
|
|
}
|
|
|
|
}
|
2015-04-30 22:22:29 +02:00
|
|
|
|
|
|
|
public static Context getActionBarThemedContext(Context base, int themeId, int accentColor) {
|
|
|
|
final int actionBarThemeId;
|
2015-05-01 05:04:08 +02:00
|
|
|
if (isDarkTheme(themeId) || TwidereColorUtils.getYIQLuminance(accentColor) <= ACCENT_COLOR_THRESHOLD) {
|
2015-04-30 22:22:29 +02:00
|
|
|
actionBarThemeId = R.style.Theme_Twidere_Dark;
|
2015-05-01 05:04:08 +02:00
|
|
|
} else {
|
|
|
|
actionBarThemeId = R.style.Theme_Twidere_Light;
|
2015-04-30 22:22:29 +02:00
|
|
|
}
|
|
|
|
final Resources.Theme baseTheme = base.getTheme();
|
|
|
|
final Resources.Theme actionBarTheme = base.getResources().newTheme();
|
|
|
|
actionBarTheme.setTo(baseTheme);
|
|
|
|
actionBarTheme.applyStyle(actionBarThemeId, true);
|
|
|
|
|
2015-05-03 16:43:05 +02:00
|
|
|
final ActionBarContextThemeWrapper actionBarContext = new ActionBarContextThemeWrapper(base, actionBarThemeId);
|
2015-04-30 22:22:29 +02:00
|
|
|
actionBarContext.getTheme().setTo(actionBarTheme);
|
|
|
|
return actionBarContext;
|
|
|
|
}
|
2015-05-03 16:43:05 +02:00
|
|
|
|
2015-05-11 18:36:18 +02:00
|
|
|
public static int getActionBarColor(Context context, int themeColor, int themeResId, String backgroundOption) {
|
|
|
|
if (!isDarkTheme(themeResId)) {
|
|
|
|
return themeColor;
|
|
|
|
} else if (isSolidBackground(backgroundOption)) {
|
|
|
|
return Color.BLACK;
|
|
|
|
}
|
|
|
|
return context.getResources().getColor(R.color.background_color_action_bar_dark);
|
|
|
|
}
|
|
|
|
|
2015-05-03 16:43:05 +02:00
|
|
|
public static final class ActionBarContextThemeWrapper extends android.support.v7.internal.view.ContextThemeWrapper {
|
|
|
|
|
|
|
|
public ActionBarContextThemeWrapper(Context base, int themeres) {
|
|
|
|
super(base, themeres);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int getActionBarThemeResource(int themeId, int accentColor) {
|
|
|
|
if (isDarkTheme(themeId) || TwidereColorUtils.getYIQLuminance(accentColor) <= ACCENT_COLOR_THRESHOLD) {
|
|
|
|
return R.style.Theme_Twidere_Dark;
|
|
|
|
} else {
|
|
|
|
return R.style.Theme_Twidere_Light;
|
|
|
|
}
|
|
|
|
}
|
2014-07-03 07:48:39 +02:00
|
|
|
}
|