package com.amaze.filemanager.utils.color; import android.content.Context; import android.content.SharedPreferences; import android.content.res.Resources; import android.graphics.drawable.ColorDrawable; import android.support.annotation.ColorInt; import android.support.annotation.ColorRes; import android.util.Log; import com.amaze.filemanager.R; import com.amaze.filemanager.utils.Utils; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; /** * The ColorPreference class stores the user's preference for each {@link ColorUsage} and provides tools to: * - Access these colors as recource id, interer representation or String representation * - Load and save the preferences in a {@link SharedPreferences} object */ public class ColorPreference { public static final List<Integer> availableColors = Arrays.asList( R.color.primary_red, R.color.primary_pink, R.color.primary_purple, R.color.primary_deep_purple, R.color.primary_indigo, R.color.primary_blue, R.color.primary_light_blue, R.color.primary_cyan, R.color.primary_teal, R.color.primary_green, R.color.primary_light_green, R.color.primary_amber, R.color.primary_orange, R.color.primary_deep_orange, R.color.primary_brown, R.color.primary_grey_900, R.color.primary_blue_grey, R.color.primary_teal_900 ); private Map<ColorUsage, Integer> colors; private Context context; private ColorPreference(Context context) { this.context = context; this.colors = new HashMap<>(); } /** * Compatibility code for use with legacy. Returns the index of the ColorResource given in the availableColors array. * Used for storing the color prefererences in the {@link SharedPreferences} object. * * @param colorResource The resouce * @return Its index in the availableColors array. */ @Deprecated private static int colorIndex(@ColorRes int colorResource) { return availableColors.indexOf(colorResource); } /** * Compatibility code for use zith legacy. Retrieves a ColorResource given its index in the availableColors array. * Used to load color preferences from the {@link SharedPreferences} object. * * @param colorIndex An index * @return The color with the given index. */ @Deprecated @ColorRes private static int getColorByIndex(int colorIndex) { return availableColors.get(colorIndex); } public static ColorPreference loadFromPreferences(Context context, SharedPreferences preferences) { ColorPreference cp = new ColorPreference(context); boolean prefCorrupted = false; for (ColorUsage usage : ColorUsage.values()) { try { int val = preferences.getInt(usage.asString(), colorIndex(usage.getDefaultColor())); cp.setRes(usage, getColorByIndex(val)); } catch (ClassCastException ex) { Log.d("ColorPreference", "Got a ClassCastException while retrieving preference " + usage.asString()); cp.setRes(usage, usage.getDefaultColor()); prefCorrupted = true; } } if (prefCorrupted) { cp.saveToPreferences(preferences); } return cp; } /** * Combinations used when randimizing color selection at startup. */ private static int[][] combinations = new int[][]{ {14, 11, 12}, {4, 1, 4}, {8, 12, 8}, {17, 11, 12}, {3, 1, 3}, {16, 14, 16}, {1, 12, 1}, {16, 0, 16}, {0, 12, 0}, {6, 1, 6}, {7, 1, 7} }; /** * Randomizes (but does not save) the colors used by the interface. * * @return The {@link ColorPreference} object itself. */ public ColorPreference randomize() { int[] colorPos = combinations[new Random().nextInt(combinations.length - 1)]; setRes(ColorUsage.PRIMARY, getColorByIndex(colorPos[0])); setRes(ColorUsage.PRIMARY_TWO, getColorByIndex(colorPos[0])); setRes(ColorUsage.ACCENT, getColorByIndex(colorPos[1])); setRes(ColorUsage.ICON_SKIN, getColorByIndex(colorPos[2])); return this; } /** * Saves the colors preferences in the {@link SharedPreferences} object given. * * @param preferences The {@link SharedPreferences} object in which the preferences are stored * @return The {@link ColorPreference} object itself. */ public ColorPreference saveToPreferences(SharedPreferences preferences) { SharedPreferences.Editor e = preferences.edit(); for (ColorUsage usage : colors.keySet()) { e.putInt(usage.asString(), colorIndex(getRes(usage))); } e.apply(); Log.d("ColorPreference", "ColorPreference saved to SharedPreferences successfully."); return this; } /** * Sets the color resource for the given {@link ColorUsage} * * @param usage The {@link ColorUsage} * @param color The new color * @return The {@link ColorPreference} instance itself. */ public ColorPreference setRes(ColorUsage usage, @ColorRes int color) { colors.put(usage, color); return this; } /** * Get the color resource preference for the given {@link ColorUsage} * * @param usage The {@link ColorUsage} * @return The color resource id. */ @ColorRes private int getRes(ColorUsage usage) { @ColorRes Integer color = colors.get(usage); return color == null ? usage.getDefaultColor() : color; } /** * Get the color preference for the given {@link ColorUsage} * * @param usage The {@link ColorUsage} * @return The color int. */ @ColorInt public int getColor(ColorUsage usage) { try { return Utils.getColor(context, getRes(usage)); } catch (Resources.NotFoundException ex) { Log.e("ColorPreference", "Color resource not found for " + usage.asString() + ": " + Integer.toString(getRes(usage))); return Utils.getColor(context, usage.getDefaultColor()); } } /** * Shortcut to get a {@link ColorDrawable} of the color preference associated with the given {@link ColorUsage} * * @param usage The {@link ColorUsage} * @return The {@link ColorDrawable} */ public ColorDrawable getDrawable(ColorUsage usage) { return new ColorDrawable(getColor(usage)); } /** * Get the color representation assiciated with the {@link ColorUsage} as a 6-digit Hexadecimal String * * @param usage The {@link ColorUsage} * @return The hex String */ @Deprecated public String getColorAsString(ColorUsage usage) { return String.format("#%06X", (0xFFFFFF & getColor(usage))); } }