/** * ******************************************************************************* * Copyright 2015 Tom Praschan * <p/> * 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 * <p/> * http://www.apache.org/licenses/LICENSE-2.0 * <p/> * 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. * ****************************************************************************** * <p/> * Inspired by the excellent Reddit App Slide: https://github.com/ccrama/Slide */ package de.tap.easy_xkcd.utils; import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.content.res.ColorStateList; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.ColorFilter; import android.graphics.ColorMatrixColorFilter; import android.preference.PreferenceManager; import android.support.design.widget.NavigationView; import android.support.v4.content.ContextCompat; import android.support.v4.util.CircularArray; import android.support.v7.graphics.Palette; import android.util.Log; import com.tap.xkcd_reader.R; import java.util.Calendar; public class ThemePrefs { private Context context; private static final String THEME = "pref_theme"; private static final String COLOR_PRIMARY = "pref_color_primary"; private static final String COLOR_PRIMARY_DARK = "pref_color_primary_dark"; private static final String COLOR_ACCENT = "pref_color_accent"; private static final String COLOR_ACCENT_NIGHT = "pref_color_accent_night"; private static final String NIGHT_THEME = "pref_night"; private static final String WHATIF_NIGHT_MODE = "night_mode"; private static final String AUTO_NIGHT = "pref_auto_night"; private static final String AUTO_NIGHT_START_MIN = "pref_auto_night_start_min"; private static final String AUTO_NIGHT_START_HOUR = "pref_auto_night_start_hour"; private static final String AUTO_NIGHT_END_MIN = "pref_auto_night_end_min"; private static final String AUTO_NIGHT_END_HOUR = "pref_auto_night_end_hour"; private static final String INVERT_COLORS = "pref_invert"; public ThemePrefs(Context context) { this.context = context; } public boolean WhatIfNightModeEnabled() { return getSharedPrefs().getBoolean(WHATIF_NIGHT_MODE, false); } public void setWhatIfNightMode(boolean value) { getSharedPrefs().edit().putBoolean(WHATIF_NIGHT_MODE, value).apply(); } public int[] getAutoNightStart() { return new int[]{ getSharedPrefs().getInt(AUTO_NIGHT_START_HOUR, 21), getSharedPrefs().getInt(AUTO_NIGHT_START_MIN, 0) }; } public int[] getAutoNightEnd() { return new int[]{ getSharedPrefs().getInt(AUTO_NIGHT_END_HOUR, 8), getSharedPrefs().getInt(AUTO_NIGHT_END_MIN, 0) }; } public void setAutoNightStart(int[] time) { editSharedPrefs() .putInt(AUTO_NIGHT_START_HOUR, time[0]) .putInt(AUTO_NIGHT_START_MIN, time[1]) .apply(); } public void setAutoNightEnd(int[] time) { editSharedPrefs() .putInt(AUTO_NIGHT_END_HOUR, time[0]) .putInt(AUTO_NIGHT_END_MIN, time[1]) .apply(); } public String getStartSummary() { int[] start = getAutoNightStart(); String suffix = ""; String minute = String.valueOf(start[1]); if (start[1] < 10) { minute = "0" + minute; } return start[0] + ":" + minute + suffix; } public String getEndSummary() { int[] end = getAutoNightEnd(); String suffix = ""; String minute = String.valueOf(end[1]); if (end[1] < 10) { minute = "0" + minute; } return end[0] + ":" + minute + suffix; } public boolean autoNightEnabled() { return getPrefs().getBoolean(AUTO_NIGHT, false); } public void setNightThemeEnabled(boolean enabled) { getPrefs().edit().putBoolean(NIGHT_THEME, enabled).apply(); setWhatIfNightMode(enabled); } public boolean nightEnabledThemeIgnoreAutoNight() { return getPrefs().getBoolean(NIGHT_THEME, false); } public boolean nightThemeEnabled() { try { if (getPrefs().getBoolean(NIGHT_THEME, false) && autoNightEnabled()) { int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY); int minute = Calendar.getInstance().get(Calendar.MINUTE); int[] start = getAutoNightStart(); int[] end = getAutoNightEnd(); if (hour == start[0]) { return minute >= start[1]; } if (hour == end[0]) { return minute < end[1]; } if (hour > start[0] && hour > end[0] && end[0] >= start[0]) { return false; } if (hour > start[0]) { return end[0] <= start[0] || hour < end[0]; } else { return hour < end[0]; } } else { return getPrefs().getBoolean(NIGHT_THEME, false); } } catch (NullPointerException e) { Log.e("error", "night theme null pointer"); return false; } } public int getNewTheme() { int accent = getSharedPrefs().getInt(COLOR_ACCENT, -1); if (accent == -1) accent = importOldTheme(); if (nightThemeEnabled()) { accent = getAccentColorNight(); if (accent == getColor(R.color.AccentPurple)) return R.style.PurpleNightTheme; if (accent == getColor(R.color.AccentIndigo)) return R.style.IndigoNightTheme; if (accent == getColor(R.color.AccentBlue)) return R.style.BlueNightTheme; if (accent == getColor(R.color.AccentLightBlue)) return R.style.LightBlueNightTheme; if (accent == getColor(R.color.AccentCyan)) return R.style.CyanNightTheme; if (accent == getColor(R.color.AccentTeal)) return R.style.TealNightTheme; if (accent == getColor(R.color.AccentGreen)) return R.style.GreenNightTheme; if (accent == getColor(R.color.AccentLightGreen)) return R.style.LightBlueNightTheme; if (accent == getColor(R.color.AccentLime)) return R.style.LimeNightTheme; if (accent == getColor(R.color.AccentYellow)) return R.style.YellowNightTheme; if (accent == getColor(R.color.AccentAmber)) return R.style.AmberNightTheme; if (accent == getColor(R.color.AccentOrange)) return R.style.OrangeNightTheme; if (accent == getColor(R.color.AccentDeepOrange)) return R.style.DeepOrangeNightTheme; if (accent == getColor(R.color.AccentRed)) return R.style.RedNightTheme; return R.style.LimeNightTheme; } else { if (accent == getColor(R.color.AccentPurple)) return R.style.PurpleTheme; if (accent == getColor(R.color.AccentIndigo)) return R.style.IndigoTheme; if (accent == getColor(R.color.AccentBlue)) return R.style.BlueTheme; if (accent == getColor(R.color.AccentLightBlue)) return R.style.LightBlueTheme; if (accent == getColor(R.color.AccentCyan)) return R.style.CyanTheme; if (accent == getColor(R.color.AccentTeal)) return R.style.TealTheme; if (accent == getColor(R.color.AccentGreen)) return R.style.GreenTheme; if (accent == getColor(R.color.AccentLightGreen)) return R.style.LightBlueTheme; if (accent == getColor(R.color.AccentLime)) return R.style.LimeTheme; if (accent == getColor(R.color.AccentYellow)) return R.style.YellowTheme; if (accent == getColor(R.color.AccentAmber)) return R.style.AmberTheme; if (accent == getColor(R.color.AccentOrange)) return R.style.OrangeTheme; if (accent == getColor(R.color.AccentDeepOrange)) return R.style.DeepOrangeTheme; if (accent == getColor(R.color.AccentRed)) return R.style.RedTheme; return R.style.LimeTheme; } } public int importOldTheme() { int oldTheme = getOldTheme(); int oldAccent, oldPrimary; switch (oldTheme) { case 2: oldAccent = R.color.AccentBlue; oldPrimary = R.color.PrimaryRed; break; case 3: oldAccent = R.color.AccentOrange; oldPrimary = R.color.PrimaryBlue; break; case 4: oldAccent = R.color.AccentOrange; oldPrimary = R.color.PrimaryBlack; break; case 5: oldAccent = R.color.AccentRed; oldPrimary = R.color.PrimaryPurple; break; case 6: oldAccent = R.color.AccentRed; oldPrimary = R.color.PrimaryLime; break; case 7: oldAccent = R.color.AccentRed; oldPrimary = R.color.PrimaryGreen; break; default: oldAccent = R.color.AccentLime; oldPrimary = R.color.PrimaryBlueGrey; } setNewTheme(getColor(oldAccent)); setPrimaryColor(getColor(oldPrimary)); return getColor(oldAccent); } public int getOldTheme() { return Integer.parseInt(getPrefs().getString(THEME, "1")); } public void setNewTheme(int accentColor) { editSharedPrefs().putInt(COLOR_ACCENT, accentColor).apply(); } public int getAccentColorNight() { return getSharedPrefs().getInt(COLOR_ACCENT_NIGHT, getAccentColor()); } public void setAccentColorNight(int color) { editSharedPrefs().putInt(COLOR_ACCENT_NIGHT, color).apply(); } public void setupNavdrawerColor(NavigationView navigationView) { int[][] state = new int[][]{ new int[]{-android.R.attr.state_checked}, new int[]{} }; int[] color = new int[]{ getNavDrawerTextColor(), getNavDrawerHightlightColor() }; int[] colorIcon = new int[]{ getColor(android.R.color.tertiary_text_light), getNavDrawerHightlightColor() }; navigationView.setItemTextColor(new ColorStateList(state, color)); navigationView.setItemIconTintList(new ColorStateList(state, colorIcon)); } public int getNavDrawerHightlightColor() { if (!nightThemeEnabled()) return getPrimaryColor(true); return getAccentColorNight(); } public int getNavDrawerTextColor() { if (!nightThemeEnabled()) return Color.BLACK; return Color.WHITE; } public int getPrimaryColor(boolean ignoreNightTheme) { if (ignoreNightTheme || !nightThemeEnabled()) return getSharedPrefs().getInt(COLOR_PRIMARY, getColor(R.color.PrimaryBlueGrey)); return Color.BLACK; } public int getAccentColor() { return getSharedPrefs().getInt(COLOR_ACCENT, getColor(R.color.AccentLime)); } public void setPrimaryColor(int color) { editSharedPrefs().putInt(COLOR_PRIMARY, color).apply(); int[] colors = getPrimaryColors(); for (int i = 0; i < colors.length; i++) if (colors[i] == color) editSharedPrefs().putInt(COLOR_PRIMARY_DARK, getPrimaryDarkColors()[i]).apply(); } public int getPrimaryDarkColor() { if (!nightThemeEnabled()) return getSharedPrefs().getInt(COLOR_PRIMARY_DARK, getColor(R.color.PrimaryDarkBlueGrey)); return Color.BLACK; } public boolean invertColors(boolean fromWhatIf) { return getPrefs().getBoolean(INVERT_COLORS, true) && (nightThemeEnabled() || (WhatIfNightModeEnabled() && fromWhatIf)); } public int[] getAccentColors() { return new int[]{ getColor(R.color.AccentPurple), getColor(R.color.AccentIndigo), getColor(R.color.AccentBlue), getColor(R.color.AccentLightBlue), getColor(R.color.AccentCyan), getColor(R.color.AccentTeal), getColor(R.color.AccentGreen), //getColor(R.color.AccentLightGreen), this color didn't work for some reason getColor(R.color.AccentLime), getColor(R.color.AccentYellow), getColor(R.color.AccentAmber), getColor(R.color.AccentOrange), getColor(R.color.AccentDeepOrange), getColor(R.color.AccentRed), }; } public int[] getPrimaryColors() { return new int[]{ getColor(R.color.PrimaryPurple), getColor(R.color.PrimaryDeepPurple), getColor(R.color.PrimaryIndigo), getColor(R.color.PrimaryBlue), getColor(R.color.PrimaryLightBlue), getColor(R.color.PrimaryCyan), getColor(R.color.PrimaryTeal), getColor(R.color.PrimaryGreen), getColor(R.color.PrimaryLightGreen), getColor(R.color.PrimaryLime), getColor(R.color.PrimaryYellow), getColor(R.color.PrimaryAmber), getColor(R.color.PrimaryOrange), getColor(R.color.PrimaryDeepOrange), getColor(R.color.PrimaryRed), getColor(R.color.PrimaryBrown), getColor(R.color.PrimaryGrey), getColor(R.color.PrimaryBlueGrey), getColor(R.color.PrimaryBlack) }; } public int[] getPrimaryDarkColors() { return new int[]{ getColor(R.color.PrimaryDarkPurple), getColor(R.color.PrimaryDarkDeepPurple), getColor(R.color.PrimaryDarkIndigo), getColor(R.color.PrimaryDarkBlue), getColor(R.color.PrimaryDarkLightBlue), getColor(R.color.PrimaryDarkCyan), getColor(R.color.PrimaryDarkTeal), getColor(R.color.PrimaryDarkGreen), getColor(R.color.PrimaryDarkLightGreen), getColor(R.color.PrimaryDarkLime), getColor(R.color.PrimaryDarkYellow), getColor(R.color.PrimaryDarkAmber), getColor(R.color.PrimaryDarkOrange), getColor(R.color.PrimaryDarkDeepOrange), getColor(R.color.PrimaryDarkRed), getColor(R.color.PrimaryDarkBrown), getColor(R.color.PrimaryDarkGrey), getColor(R.color.PrimaryDarkBlueGrey), getColor(R.color.PrimaryDarkBlack) }; } public ColorFilter getNegativeColorFilter() { float[] colorMatrix_Negative = { -1.0f, 0, 0, 0, 255, //red 0, -1.0f, 0, 0, 255, //green 0, 0, -1.0f, 0, 255, //blue 0, 0, 0, 1.0f, 0 //alpha }; return new ColorMatrixColorFilter(colorMatrix_Negative); } public boolean bitmapContainsColor(Bitmap bitmap) { Palette palette = Palette.from(bitmap).generate(); return palette.getVibrantSwatch() != null; } private int getColor(int color) { return ContextCompat.getColor(context, color); } private SharedPreferences getSharedPrefs() { return context.getSharedPreferences("MainActivity", Activity.MODE_PRIVATE); } private SharedPreferences getPrefs() { return PreferenceManager.getDefaultSharedPreferences(context); } private SharedPreferences.Editor editSharedPrefs() { return context.getSharedPreferences("MainActivity", Activity.MODE_PRIVATE).edit(); } }