From b6b7e61cfba1685cc6f6e0683a3c1f8276a715d6 Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Thu, 12 Apr 2018 19:21:53 +0200 Subject: [PATCH] Add tint for icon pack --- .../keepass/activities/EntryActivity.java | 25 +++++++++------ .../keepass/activities/GroupActivity.java | 14 +++++++- .../keepass/adapters/NodeAdapter.java | 32 +++++++++++++++++-- .../dialogs/IconPickerDialogFragment.java | 14 ++++++++ .../keepass/icons/DrawableFactory.java | 30 +++++++++++++---- .../com/kunzisoft/keepass/icons/IconPack.java | 24 ++++++++++++-- .../src/main/res/values/strings.xml | 1 + .../src/main/res/values/strings.xml | 1 + 8 files changed, 119 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.java b/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.java index 1704084f3..11228db74 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.java +++ b/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.java @@ -23,7 +23,8 @@ package com.kunzisoft.keepass.activities; import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Intent; -import android.graphics.drawable.Drawable; +import android.content.res.TypedArray; +import android.graphics.Color; import android.net.Uri; import android.os.Bundle; import android.os.Handler; @@ -45,6 +46,7 @@ import com.kunzisoft.keepass.database.ExtraFields; import com.kunzisoft.keepass.database.PwDatabase; import com.kunzisoft.keepass.database.PwEntry; import com.kunzisoft.keepass.database.security.ProtectedString; +import com.kunzisoft.keepass.icons.IconPackChooser; import com.kunzisoft.keepass.notifications.NotificationCopyingService; import com.kunzisoft.keepass.notifications.NotificationField; import com.kunzisoft.keepass.settings.PreferencesUtil; @@ -277,20 +279,25 @@ public class EntryActivity extends LockingHideActivity { } } - private void populateTitle(Drawable drawIcon, String text) { - titleIconView.setImageDrawable(drawIcon); - titleView.setText(text); - } - protected void fillData() { Database db = App.getDB(); PwDatabase pm = db.getPwDatabase(); mEntry.startToManageFieldReferences(pm); - // Assign title - populateTitle(db.getDrawFactory().getIconDrawable(this, mEntry.getIcon()), - mEntry.getTitle()); + // Assign title icon + if (IconPackChooser.getDefaultIconPack(this).tintable()) { + // Retrieve the textColor to tint the icon + int[] attrs = {R.attr.textColorInverse}; + TypedArray ta = getTheme().obtainStyledAttributes(attrs); + int iconColor = ta.getColor(0, Color.WHITE); + App.getDB().getDrawFactory().assignDrawableTo(this, titleIconView, mEntry.getIcon(), true, iconColor); + } else { + App.getDB().getDrawFactory().assignDrawableTo(this, titleIconView, mEntry.getIcon()); + } + + // Assign title text + titleView.setText(mEntry.getTitle()); // Assign basic fields entryContentsView.assignUserName(mEntry.getUsername()); diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.java b/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.java index 4b41a7fe8..d0fc2fe83 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.java +++ b/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.java @@ -27,6 +27,8 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.content.res.TypedArray; +import android.graphics.Color; import android.os.Build; import android.os.Bundle; import android.os.Handler; @@ -60,6 +62,7 @@ import com.kunzisoft.keepass.dialogs.AssignMasterKeyDialogFragment; import com.kunzisoft.keepass.dialogs.GroupEditDialogFragment; import com.kunzisoft.keepass.dialogs.IconPickerDialogFragment; import com.kunzisoft.keepass.dialogs.ReadOnlyDialog; +import com.kunzisoft.keepass.icons.IconPackChooser; import com.kunzisoft.keepass.search.SearchResultsActivity; import com.kunzisoft.keepass.settings.PreferencesUtil; import com.kunzisoft.keepass.tasks.ProgressTask; @@ -407,7 +410,16 @@ public class GroupActivity extends ListNodesActivity protected void setGroupIcon() { if (mCurrentGroup != null) { ImageView iv = findViewById(R.id.icon); - App.getDB().getDrawFactory().assignDrawableTo(this, iv, mCurrentGroup.getIcon()); + + if (IconPackChooser.getDefaultIconPack(this).tintable()) { + // Retrieve the textColor to tint the icon + int[] attrs = {R.attr.textColorInverse}; + TypedArray ta = getTheme().obtainStyledAttributes(attrs); + int iconColor = ta.getColor(0, Color.WHITE); + App.getDB().getDrawFactory().assignDrawableTo(this, iv, mCurrentGroup.getIcon(), true, iconColor); + } else { + App.getDB().getDrawFactory().assignDrawableTo(this, iv, mCurrentGroup.getIcon()); + } } } diff --git a/app/src/main/java/com/kunzisoft/keepass/adapters/NodeAdapter.java b/app/src/main/java/com/kunzisoft/keepass/adapters/NodeAdapter.java index a48dbb16d..a23095adc 100644 --- a/app/src/main/java/com/kunzisoft/keepass/adapters/NodeAdapter.java +++ b/app/src/main/java/com/kunzisoft/keepass/adapters/NodeAdapter.java @@ -20,6 +20,9 @@ package com.kunzisoft.keepass.adapters; import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Color; +import android.support.annotation.NonNull; import android.support.v7.util.SortedList; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.util.SortedListAdapterCallback; @@ -36,6 +39,7 @@ import com.kunzisoft.keepass.app.App; import com.kunzisoft.keepass.database.PwGroup; import com.kunzisoft.keepass.database.PwNode; import com.kunzisoft.keepass.database.SortNodeEnum; +import com.kunzisoft.keepass.icons.IconPackChooser; import com.kunzisoft.keepass.settings.PreferencesUtil; public class NodeAdapter extends RecyclerView.Adapter { @@ -54,6 +58,9 @@ public class NodeAdapter extends RecyclerView.Adapter { private NodeMenuListener nodeMenuListener; private boolean activateContextMenu; + private int iconGroupColor; + private int iconEntryColor; + /** * Create node list adapter with contextMenu or not * @param context Context to use @@ -81,6 +88,12 @@ public class NodeAdapter extends RecyclerView.Adapter { return item1.equals(item2); } }); + + // Retrieve the color to tint the icon + int[] attrs = {android.R.attr.textColorPrimary, android.R.attr.textColor}; + TypedArray ta = context.getTheme().obtainStyledAttributes(attrs); + this.iconGroupColor = ta.getColor(0, Color.BLACK); + this.iconEntryColor = ta.getColor(1, Color.BLACK); } public void setActivateContextMenu(boolean activate) { @@ -158,7 +171,7 @@ public class NodeAdapter extends RecyclerView.Adapter { } @Override - public BasicViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + public BasicViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { BasicViewHolder basicViewHolder; View view; if (viewType == PwNode.Type.GROUP.ordinal()) { @@ -172,10 +185,23 @@ public class NodeAdapter extends RecyclerView.Adapter { } @Override - public void onBindViewHolder(BasicViewHolder holder, int position) { + public void onBindViewHolder(@NonNull BasicViewHolder holder, int position) { PwNode subNode = nodeSortedList.get(position); // Assign image - App.getDB().getDrawFactory().assignDrawableTo(context, holder.icon, subNode.getIcon()); + if (IconPackChooser.getDefaultIconPack(context).tintable()) { + int iconColor = Color.BLACK; + switch (subNode.getType()) { + case GROUP: + iconColor = iconGroupColor; + break; + case ENTRY: + iconColor = iconEntryColor; + break; + } + App.getDB().getDrawFactory().assignDrawableTo(context, holder.icon, subNode.getIcon(), true, iconColor); + } else { + App.getDB().getDrawFactory().assignDrawableTo(context, holder.icon, subNode.getIcon()); + } // Assign text holder.text.setText(subNode.getDisplayTitle()); // Assign click diff --git a/app/src/main/java/com/kunzisoft/keepass/dialogs/IconPickerDialogFragment.java b/app/src/main/java/com/kunzisoft/keepass/dialogs/IconPickerDialogFragment.java index a005e43df..f1344f487 100644 --- a/app/src/main/java/com/kunzisoft/keepass/dialogs/IconPickerDialogFragment.java +++ b/app/src/main/java/com/kunzisoft/keepass/dialogs/IconPickerDialogFragment.java @@ -21,9 +21,13 @@ package com.kunzisoft.keepass.dialogs; import android.app.Dialog; import android.content.Context; +import android.content.res.ColorStateList; +import android.content.res.TypedArray; +import android.graphics.Color; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.app.DialogFragment; +import android.support.v4.widget.ImageViewCompat; import android.support.v7.app.AlertDialog; import android.view.LayoutInflater; import android.view.View; @@ -124,6 +128,16 @@ public class IconPickerDialogFragment extends DialogFragment { ImageView iv = currView.findViewById(R.id.icon_image); iv.setImageResource(iconPack.iconToResId(position)); + // Assign color if icons are tintable + if (iconPack.tintable()) { + // Retrieve the textColor to tint the icon + int[] attrs = {android.R.attr.textColor}; + assert getContext() != null; + TypedArray ta = getContext().getTheme().obtainStyledAttributes(attrs); + int iconColor = ta.getColor(0, Color.BLACK); + ImageViewCompat.setImageTintList(iv, ColorStateList.valueOf(iconColor)); + } + return currView; } } diff --git a/app/src/main/java/com/kunzisoft/keepass/icons/DrawableFactory.java b/app/src/main/java/com/kunzisoft/keepass/icons/DrawableFactory.java index 9cec54ec2..c09fcfe06 100644 --- a/app/src/main/java/com/kunzisoft/keepass/icons/DrawableFactory.java +++ b/app/src/main/java/com/kunzisoft/keepass/icons/DrawableFactory.java @@ -20,12 +20,14 @@ package com.kunzisoft.keepass.icons; import android.content.Context; +import android.content.res.ColorStateList; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.support.v4.widget.ImageViewCompat; import android.widget.ImageView; import com.kunzisoft.keepass.R; @@ -41,6 +43,7 @@ public class DrawableFactory { private static Drawable blank = null; private static int blankWidth = -1; private static int blankHeight = -1; + private boolean iconStandardToTint = false; /** customIconMap * Cache for icon drawable. @@ -53,19 +56,33 @@ public class DrawableFactory { * Keys: Integer, Values: Drawables */ private ReferenceMap standardIconMap = new ReferenceMap(AbstractReferenceMap.HARD, AbstractReferenceMap.WEAK); - + public void assignDrawableTo(Context context, ImageView iv, PwIcon icon) { - Drawable draw = getIconDrawable(context, icon); - if (iv != null && draw != null) - iv.setImageDrawable(draw); + assignDrawableTo(context, iv, icon, false, -1); } + + public void assignDrawableTo(Context context, ImageView iv, PwIcon icon, boolean tint, int tintColor) { + Drawable draw = getIconDrawable(context, icon); + if (iv != null && draw != null) { + iv.setImageDrawable(draw); + if (iconStandardToTint && tint) { + ImageViewCompat.setImageTintList(iv, ColorStateList.valueOf(tintColor)); + } + } + iconStandardToTint = false; + } public Drawable getIconDrawable(Context context, PwIcon icon) { + Drawable sharedDrawable; if (icon instanceof PwIconStandard) { - return getIconDrawable(context, (PwIconStandard) icon); + iconStandardToTint = true; + sharedDrawable = getIconDrawable(context, (PwIconStandard) icon); } else { - return getIconDrawable(context, (PwIconCustom) icon); + iconStandardToTint = false; + sharedDrawable = getIconDrawable(context, (PwIconCustom) icon); } + assert sharedDrawable.getConstantState() != null; + return sharedDrawable.getConstantState().newDrawable(); } private static void initBlank(Resources res) { @@ -119,6 +136,7 @@ public class DrawableFactory { } /** Resize the custom icon to match the built in icons + * * @param bitmap * @return */ diff --git a/app/src/main/java/com/kunzisoft/keepass/icons/IconPack.java b/app/src/main/java/com/kunzisoft/keepass/icons/IconPack.java index edf245ac1..4c7cb873a 100644 --- a/app/src/main/java/com/kunzisoft/keepass/icons/IconPack.java +++ b/app/src/main/java/com/kunzisoft/keepass/icons/IconPack.java @@ -44,9 +44,11 @@ public class IconPack { private static final int NB_ICONS = 68; private static SparseIntArray icons = null; + private boolean tintable = false; private Resources resources; + /** * Construct dynamically the icon pack provide by the default string resource "resource_prefix" * @@ -71,12 +73,28 @@ public class IconPack { icons = new SparseIntArray(); while(num <= NB_ICONS) { // To construct the id with prefix_ic_XX_32dp (ex : classic_ic_08_32dp ) - String drawableIdString = new DecimalFormat("00").format(num) + "_32dp"; - String drawableIdStringWithPrefix = context.getString(resourcePrefixId) + drawableIdString; - int resId = resources.getIdentifier(drawableIdStringWithPrefix, "drawable", context.getPackageName()); + int resId = resources.getIdentifier( + context.getString(resourcePrefixId) + new DecimalFormat("00").format(num) + "_32dp", + "drawable", + context.getPackageName()); icons.put(num, resId); num++; } + // If icons are tintable + tintable = resources.getBoolean( + resources.getIdentifier( + context.getString(resourcePrefixId) + "tintable", + "bool", + context.getPackageName()) ); + } + + /** + * Determine if each icon in the pack can be tint + * + * @return true if icons are tintable + */ + public boolean tintable() { + return tintable; } /** diff --git a/icon-pack-classic/src/main/res/values/strings.xml b/icon-pack-classic/src/main/res/values/strings.xml index b1854e4ee..47c7913a0 100644 --- a/icon-pack-classic/src/main/res/values/strings.xml +++ b/icon-pack-classic/src/main/res/values/strings.xml @@ -20,4 +20,5 @@ classic_ + false diff --git a/icon-pack-material/src/main/res/values/strings.xml b/icon-pack-material/src/main/res/values/strings.xml index 280bae4ce..0647857d9 100644 --- a/icon-pack-material/src/main/res/values/strings.xml +++ b/icon-pack-material/src/main/res/values/strings.xml @@ -20,4 +20,5 @@ material_ + true