From c41158f432bea16f10353f124fc5a326299926e4 Mon Sep 17 00:00:00 2001 From: M66B Date: Wed, 27 Nov 2013 15:22:51 +0100 Subject: [PATCH] Modified tri-state check box implementation Refs #833 --- CHANGELOG.md | 1 + src/biz/bokhorst/xprivacy/ActivityApp.java | 32 +++++------- src/biz/bokhorst/xprivacy/ActivityMain.java | 31 ++++++------ src/biz/bokhorst/xprivacy/ActivityShare.java | 1 - src/biz/bokhorst/xprivacy/Requirements.java | 17 ++----- src/biz/bokhorst/xprivacy/SettingsDialog.java | 9 +--- src/biz/bokhorst/xprivacy/Util.java | 49 +++++++++++++------ 7 files changed, 66 insertions(+), 74 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a197634a1..5f4adcdf7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Changelog * Caching of application information for better response times * Restriction of draw over / on top ([issue](https://github.com/M66B/XPrivacy/issues/830)) +* Modified tri-state check box implementation ([issue](https://github.com/M66B/XPrivacy/issues/833)) * Updated Arabic translation * Updated Dutch translation * Updated Polish translation diff --git a/src/biz/bokhorst/xprivacy/ActivityApp.java b/src/biz/bokhorst/xprivacy/ActivityApp.java index f4e63a8b4..f724b5a6c 100644 --- a/src/biz/bokhorst/xprivacy/ActivityApp.java +++ b/src/biz/bokhorst/xprivacy/ActivityApp.java @@ -64,7 +64,6 @@ import android.support.v4.app.NavUtils; import android.support.v4.app.NotificationCompat; import android.support.v4.app.TaskStackBuilder; -import android.util.TypedValue; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -155,7 +154,7 @@ public void onClick(View view) { // Background color if (mAppInfo.isSystem()) { LinearLayout llInfo = (LinearLayout) findViewById(R.id.llInfo); - llInfo.setBackgroundColor(getResources().getColor(getThemed(R.attr.color_dangerous))); + llInfo.setBackgroundColor(getResources().getColor(Util.getThemed(this, R.attr.color_dangerous))); } // Display app icon @@ -374,7 +373,7 @@ private void optionHelp() { dialog.requestWindowFeature(Window.FEATURE_LEFT_ICON); dialog.setTitle(getString(R.string.help_application)); dialog.setContentView(R.layout.help); - dialog.setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, getThemed(R.attr.icon_launcher)); + dialog.setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, Util.getThemed(this, R.attr.icon_launcher)); TextView tvHelpHalf = (TextView) dialog.findViewById(R.id.help_half); Drawable dHalf = new BitmapDrawable(getResources(), mCheck[1]); dHalf.setBounds(0, 0, 48, 48); @@ -387,7 +386,7 @@ private void optionApply() { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ActivityApp.this); alertDialogBuilder.setTitle(getString(R.string.app_name)); alertDialogBuilder.setMessage(getString(R.string.msg_sure)); - alertDialogBuilder.setIcon(getThemed(R.attr.icon_launcher)); + alertDialogBuilder.setIcon(Util.getThemed(this, R.attr.icon_launcher)); alertDialogBuilder.setPositiveButton(getString(android.R.string.ok), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { @@ -429,7 +428,7 @@ private void optionClear() { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ActivityApp.this); alertDialogBuilder.setTitle(getString(R.string.app_name)); alertDialogBuilder.setMessage(getString(R.string.msg_sure)); - alertDialogBuilder.setIcon(getThemed(R.attr.icon_launcher)); + alertDialogBuilder.setIcon(Util.getThemed(this, R.attr.icon_launcher)); alertDialogBuilder.setPositiveButton(getString(android.R.string.ok), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { @@ -458,7 +457,7 @@ private void optionSubmit() { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this); alertDialogBuilder.setTitle(getString(R.string.app_name)); alertDialogBuilder.setMessage(getString(R.string.msg_sure)); - alertDialogBuilder.setIcon(getThemed(R.attr.icon_launcher)); + alertDialogBuilder.setIcon(Util.getThemed(this, R.attr.icon_launcher)); alertDialogBuilder.setPositiveButton(getString(android.R.string.ok), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { @@ -562,7 +561,7 @@ protected void onPostExecute(Object result) { // Build dialog AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ActivityApp.this); alertDialogBuilder.setTitle(getString(R.string.menu_accounts)); - alertDialogBuilder.setIcon(getThemed(R.attr.icon_launcher)); + alertDialogBuilder.setIcon(Util.getThemed(ActivityApp.this, R.attr.icon_launcher)); alertDialogBuilder.setMultiChoiceItems(mListAccount.toArray(new CharSequence[0]), mSelection, new DialogInterface.OnMultiChoiceClickListener() { public void onClick(DialogInterface dialog, int whichButton, boolean isChecked) { @@ -631,7 +630,7 @@ protected void onPostExecute(Object result) { // Build dialog AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ActivityApp.this); alertDialogBuilder.setTitle(getString(R.string.menu_applications)); - alertDialogBuilder.setIcon(getThemed(R.attr.icon_launcher)); + alertDialogBuilder.setIcon(Util.getThemed(ActivityApp.this, R.attr.icon_launcher)); alertDialogBuilder.setMultiChoiceItems(mListApp.toArray(new CharSequence[0]), mSelection, new DialogInterface.OnMultiChoiceClickListener() { public void onClick(DialogInterface dialog, int whichButton, boolean isChecked) { @@ -707,7 +706,7 @@ protected void onPostExecute(Object result) { // Build dialog AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ActivityApp.this); alertDialogBuilder.setTitle(getString(R.string.menu_contacts)); - alertDialogBuilder.setIcon(getThemed(R.attr.icon_launcher)); + alertDialogBuilder.setIcon(Util.getThemed(ActivityApp.this, R.attr.icon_launcher)); alertDialogBuilder.setMultiChoiceItems(mListContact.toArray(new CharSequence[0]), mSelection, new DialogInterface.OnMultiChoiceClickListener() { public void onClick(DialogInterface dialog, int whichButton, boolean isChecked) { @@ -1040,8 +1039,8 @@ public View getGroupView(int groupPosition, boolean isExpanded, View convertView final String restrictionName = (String) getGroup(groupPosition); // Indicator state - holder.imgIndicator.setImageResource(getThemed(isExpanded ? R.attr.icon_expander_maximized - : R.attr.icon_expander_minimized)); + holder.imgIndicator.setImageResource(Util.getThemed(ActivityApp.this, + isExpanded ? R.attr.icon_expander_maximized : R.attr.icon_expander_minimized)); // Disable indicator for empty groups if (getChildrenCount(groupPosition) == 0) @@ -1223,7 +1222,8 @@ public View getChildView(int groupPosition, int childPosition, boolean isLastChi // Set background color if (PrivacyManager.isDangerousMethod(restrictionName, md.getMethodName())) - holder.row.setBackgroundColor(getResources().getColor(getThemed(R.attr.color_dangerous))); + holder.row.setBackgroundColor(getResources().getColor( + Util.getThemed(ActivityApp.this, R.attr.color_dangerous))); else holder.row.setBackgroundColor(Color.TRANSPARENT); @@ -1254,12 +1254,4 @@ public boolean hasStableIds() { return true; } } - - // Helper methods - - private int getThemed(int attr) { - TypedValue typedvalueattr = new TypedValue(); - getTheme().resolveAttribute(attr, typedvalueattr, true); - return typedvalueattr.resourceId; - } } diff --git a/src/biz/bokhorst/xprivacy/ActivityMain.java b/src/biz/bokhorst/xprivacy/ActivityMain.java index 56d558e05..6a5685922 100644 --- a/src/biz/bokhorst/xprivacy/ActivityMain.java +++ b/src/biz/bokhorst/xprivacy/ActivityMain.java @@ -36,7 +36,6 @@ import android.text.Editable; import android.text.TextWatcher; import android.util.Log; -import android.util.TypedValue; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -171,7 +170,8 @@ public void onTextChanged(CharSequence s, int start, int before, int count) { String text = etFilter.getText().toString(); ImageView imgClear = (ImageView) findViewById(R.id.imgClear); imgClear.setImageDrawable(getResources().getDrawable( - getThemed(text.equals("") ? R.attr.icon_clear_grayed : R.attr.icon_clear))); + Util.getThemed(ActivityMain.this, text.equals("") ? R.attr.icon_clear_grayed + : R.attr.icon_clear))); applyFilter(); } @@ -564,7 +564,7 @@ private void optionAll() { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this); alertDialogBuilder.setTitle(getString(R.string.app_name)); alertDialogBuilder.setMessage(getString(R.string.msg_sure)); - alertDialogBuilder.setIcon(getThemed(R.attr.icon_launcher)); + alertDialogBuilder.setIcon(Util.getThemed(this, R.attr.icon_launcher)); alertDialogBuilder.setPositiveButton(getString(android.R.string.ok), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { @@ -629,7 +629,7 @@ private void optionTemplate() { // Build dialog AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this); alertDialogBuilder.setTitle(getString(R.string.menu_template)); - alertDialogBuilder.setIcon(getThemed(R.attr.icon_launcher)); + alertDialogBuilder.setIcon(Util.getThemed(this, R.attr.icon_launcher)); alertDialogBuilder.setMultiChoiceItems(options, selection, new DialogInterface.OnMultiChoiceClickListener() { public void onClick(DialogInterface dialog, int whichButton, boolean isChecked) { PrivacyManager.setSetting(null, ActivityMain.this, 0, @@ -694,7 +694,7 @@ private void optionFetch() { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this); alertDialogBuilder.setTitle(getString(R.string.app_name)); alertDialogBuilder.setMessage(getString(R.string.msg_sure)); - alertDialogBuilder.setIcon(getThemed(R.attr.icon_launcher)); + alertDialogBuilder.setIcon(Util.getThemed(this, R.attr.icon_launcher)); alertDialogBuilder.setPositiveButton(getString(android.R.string.ok), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { @@ -732,7 +732,7 @@ private void optionAbout() { dlgAbout.requestWindowFeature(Window.FEATURE_LEFT_ICON); dlgAbout.setTitle(getString(R.string.app_name)); dlgAbout.setContentView(R.layout.about); - dlgAbout.setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, getThemed(R.attr.icon_launcher)); + dlgAbout.setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, Util.getThemed(this, R.attr.icon_launcher)); // Show version try { @@ -767,7 +767,7 @@ private void optionHelp() { dialog.requestWindowFeature(Window.FEATURE_LEFT_ICON); dialog.setTitle(getString(R.string.help_application)); dialog.setContentView(R.layout.help); - dialog.setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, getThemed(R.attr.icon_launcher)); + dialog.setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, Util.getThemed(this, R.attr.icon_launcher)); TextView tvHelpHalf = (TextView) dialog.findViewById(R.id.help_half); Drawable dHalf = new BitmapDrawable(getResources(), mCheck[1]); dHalf.setBounds(0, 0, 48, 48); @@ -826,7 +826,8 @@ private void toggleFiltersVisibility() { } mFiltersHidden = !mFiltersHidden; - vFilterHighlight.setBackgroundResource(mFiltersHidden ? android.R.color.transparent : getThemed(android.R.attr.colorActivatedHighlight)); + vFilterHighlight.setBackgroundResource(mFiltersHidden ? android.R.color.transparent : Util.getThemed(this, + android.R.attr.colorActivatedHighlight)); } private void toggleCategoriesVisibility() { @@ -849,7 +850,8 @@ private void toggleCategoriesVisibility() { } mCategoriesHidden = !mCategoriesHidden; - vCategoryHighlight.setBackgroundResource(mCategoriesHidden ? android.R.color.transparent : getThemed(android.R.attr.colorActivatedHighlight)); + vCategoryHighlight.setBackgroundResource(mCategoriesHidden ? android.R.color.transparent : Util.getThemed(this, + android.R.attr.colorActivatedHighlight)); } // Tasks @@ -1201,7 +1203,7 @@ public void onClick(final View view) { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ActivityMain.this); alertDialogBuilder.setTitle(getString(R.string.app_name)); alertDialogBuilder.setMessage(getString(R.string.msg_sure)); - alertDialogBuilder.setIcon(getThemed(R.attr.icon_launcher)); + alertDialogBuilder.setIcon(Util.getThemed(ActivityMain.this, R.attr.icon_launcher)); alertDialogBuilder.setPositiveButton(getString(android.R.string.ok), new DialogInterface.OnClickListener() { @Override @@ -1267,7 +1269,8 @@ public View getView(int position, View convertView, ViewGroup parent) { // Set background color if (xAppInfo.isSystem()) - holder.row.setBackgroundColor(getResources().getColor(getThemed(R.attr.color_dangerous))); + holder.row.setBackgroundColor(getResources().getColor( + Util.getThemed(ActivityMain.this, R.attr.color_dangerous))); else holder.row.setBackgroundColor(Color.TRANSPARENT); @@ -1365,10 +1368,4 @@ private void checkLicense() { } } } - - private int getThemed(int attr) { - TypedValue typedvalueattr = new TypedValue(); - getTheme().resolveAttribute(attr, typedvalueattr, true); - return typedvalueattr.resourceId; - } } diff --git a/src/biz/bokhorst/xprivacy/ActivityShare.java b/src/biz/bokhorst/xprivacy/ActivityShare.java index 955274759..5b2430886 100644 --- a/src/biz/bokhorst/xprivacy/ActivityShare.java +++ b/src/biz/bokhorst/xprivacy/ActivityShare.java @@ -627,5 +627,4 @@ public static String getFileName(boolean multiple) { fileName = "XPrivacy.xml"; return new File(folder + File.separator + fileName).getAbsolutePath(); } - } diff --git a/src/biz/bokhorst/xprivacy/Requirements.java b/src/biz/bokhorst/xprivacy/Requirements.java index 4face4b2d..c6150592a 100644 --- a/src/biz/bokhorst/xprivacy/Requirements.java +++ b/src/biz/bokhorst/xprivacy/Requirements.java @@ -15,7 +15,6 @@ import android.net.wifi.WifiInfo; import android.os.Build; import android.util.Log; -import android.util.TypedValue; public class Requirements { @@ -30,7 +29,7 @@ public static void check(final Context context) { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context); alertDialogBuilder.setTitle(context.getString(R.string.app_name)); alertDialogBuilder.setMessage(context.getString(R.string.app_wrongandroid)); - alertDialogBuilder.setIcon(getThemed(R.attr.icon_launcher, context)); + alertDialogBuilder.setIcon(Util.getThemed(context, R.attr.icon_launcher)); alertDialogBuilder.setPositiveButton(context.getString(android.R.string.ok), new DialogInterface.OnClickListener() { @Override @@ -53,7 +52,7 @@ public void onClick(DialogInterface dialog, int which) { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context); alertDialogBuilder.setTitle(context.getString(R.string.app_name)); alertDialogBuilder.setMessage(msg); - alertDialogBuilder.setIcon(getThemed(R.attr.icon_launcher, context)); + alertDialogBuilder.setIcon(Util.getThemed(context, R.attr.icon_launcher)); alertDialogBuilder.setPositiveButton(context.getString(android.R.string.ok), new DialogInterface.OnClickListener() { @Override @@ -75,7 +74,7 @@ public void onClick(DialogInterface dialog, int which) { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context); alertDialogBuilder.setTitle(context.getString(R.string.app_name)); alertDialogBuilder.setMessage(msg); - alertDialogBuilder.setIcon(getThemed(R.attr.icon_launcher, context)); + alertDialogBuilder.setIcon(Util.getThemed(context, R.attr.icon_launcher)); alertDialogBuilder.setPositiveButton(context.getString(android.R.string.ok), new DialogInterface.OnClickListener() { @Override @@ -99,7 +98,7 @@ public void onClick(DialogInterface dialog, int which) { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context); alertDialogBuilder.setTitle(context.getString(R.string.app_name)); alertDialogBuilder.setMessage(msg); - alertDialogBuilder.setIcon(getThemed(R.attr.icon_launcher, context)); + alertDialogBuilder.setIcon(Util.getThemed(context, R.attr.icon_launcher)); alertDialogBuilder.setPositiveButton(context.getString(android.R.string.ok), new DialogInterface.OnClickListener() { @Override @@ -256,7 +255,7 @@ private static void reportClass(final Class clazz, final Context context) { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context); alertDialogBuilder.setTitle(context.getString(R.string.app_name)); alertDialogBuilder.setMessage(msg); - alertDialogBuilder.setIcon(getThemed(R.attr.icon_launcher, context)); + alertDialogBuilder.setIcon(Util.getThemed(context, R.attr.icon_launcher)); alertDialogBuilder.setPositiveButton(context.getString(android.R.string.ok), new DialogInterface.OnClickListener() { @Override @@ -323,10 +322,4 @@ private static void sendSupportInfo(String text, Context context) { Util.bug(null, ex); } } - - private static int getThemed(int attr, Context context) { - TypedValue typedvalueattr = new TypedValue(); - context.getTheme().resolveAttribute(attr, typedvalueattr, true); - return typedvalueattr.resourceId; - } } diff --git a/src/biz/bokhorst/xprivacy/SettingsDialog.java b/src/biz/bokhorst/xprivacy/SettingsDialog.java index ca340ac2b..072dbe369 100644 --- a/src/biz/bokhorst/xprivacy/SettingsDialog.java +++ b/src/biz/bokhorst/xprivacy/SettingsDialog.java @@ -8,7 +8,6 @@ import android.location.Address; import android.location.Geocoder; import android.util.Log; -import android.util.TypedValue; import android.view.View; import android.view.Window; import android.widget.Button; @@ -29,7 +28,7 @@ public static void edit(final Context context, ApplicationInfoEx appInfo) { dlgSettings.requestWindowFeature(Window.FEATURE_LEFT_ICON); dlgSettings.setTitle(context.getString(R.string.app_name)); dlgSettings.setContentView(R.layout.settings); - dlgSettings.setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, getThemed(context, R.attr.icon_launcher)); + dlgSettings.setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, Util.getThemed(context, R.attr.icon_launcher)); // Reference controls TextView tvAppName = (TextView) dlgSettings.findViewById(R.id.tvAppName); @@ -576,10 +575,4 @@ public void onClick(View view) { dlgSettings.setCancelable(true); dlgSettings.show(); } - - private static int getThemed(Context context, int attr) { - TypedValue typedvalueattr = new TypedValue(); - context.getTheme().resolveAttribute(attr, typedvalueattr, true); - return typedvalueattr.resourceId; - } } diff --git a/src/biz/bokhorst/xprivacy/Util.java b/src/biz/bokhorst/xprivacy/Util.java index 8d1cf1508..30fbabf20 100644 --- a/src/biz/bokhorst/xprivacy/Util.java +++ b/src/biz/bokhorst/xprivacy/Util.java @@ -26,15 +26,17 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; -import android.content.res.TypedArray; import android.graphics.Bitmap; -import android.graphics.BitmapFactory; +import android.graphics.Bitmap.Config; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.Paint; +import android.graphics.drawable.Drawable; import android.os.Environment; import android.os.Process; import android.util.Base64; import android.util.Log; +import android.util.TypedValue; public class Util { private static boolean mPro = false; @@ -352,28 +354,43 @@ public static void copy(File src, File dst) throws IOException { public static Bitmap[] getTriStateCheckBox(Context context) { Bitmap[] bitmap = new Bitmap[3]; - // Get highlight color - TypedArray arrayColor = context.getTheme().obtainStyledAttributes( - new int[] { android.R.attr.colorActivatedHighlight }); - int highlightColor = arrayColor.getColor(0, 0xFF00FF); - arrayColor.recycle(); + int size = 32; + int border0 = 4; + int border1 = border0 * 2; + int border2 = border0; // Create off check box - bitmap[0] = BitmapFactory.decodeResource(context.getResources(), android.R.drawable.checkbox_off_background); + bitmap[0] = Bitmap.createBitmap(size, size, Config.ARGB_8888); + Canvas canvas0 = new Canvas(bitmap[0]); + Paint paint0 = new Paint(); + paint0.setStyle(Paint.Style.STROKE); + paint0.setColor(Color.GRAY); + paint0.setStrokeWidth(2); + canvas0.drawRect(border0, border0, bitmap[0].getWidth() - border0, bitmap[0].getHeight() - border0, paint0); // Create half check box bitmap[1] = Bitmap.createBitmap(bitmap[0].getWidth(), bitmap[0].getHeight(), bitmap[0].getConfig()); - Canvas canvas = new Canvas(bitmap[1]); - Paint paint = new Paint(); - paint.setStyle(Paint.Style.FILL); - paint.setColor(highlightColor); - int border = bitmap[1].getWidth() / 3; - canvas.drawBitmap(bitmap[0], 0, 0, paint); - canvas.drawRect(border, border, bitmap[1].getWidth() - border, bitmap[1].getHeight() - border, paint); + Canvas canvas1 = new Canvas(bitmap[1]); + Paint paint1 = new Paint(); + paint1.setStyle(Paint.Style.FILL); + paint1.setColor(Color.GRAY); + canvas1.drawBitmap(bitmap[0], 0, 0, paint1); + canvas1.drawRect(border1, border1, bitmap[1].getWidth() - border1, bitmap[1].getHeight() - border1, paint1); // Create full check box - bitmap[2] = BitmapFactory.decodeResource(context.getResources(), android.R.drawable.checkbox_on_background); + bitmap[2] = Bitmap.createBitmap(bitmap[0].getWidth(), bitmap[0].getHeight(), bitmap[0].getConfig()); + Canvas canvas2 = new Canvas(bitmap[2]); + canvas2.drawBitmap(bitmap[0], 0, 0, new Paint()); + Drawable checkmark = context.getResources().getDrawable(getThemed(context, R.attr.icon_checked)); + checkmark.setBounds(border2, border2, bitmap[2].getWidth() - border2, bitmap[2].getHeight() - border2); + checkmark.draw(canvas2); return bitmap; } + + public static int getThemed(Context context, int attr) { + TypedValue tv = new TypedValue(); + context.getTheme().resolveAttribute(attr, tv, true); + return tv.resourceId; + } }