diff options
author | Stefan Niedermann <info@niedermann.it> | 2020-10-28 17:09:09 +0300 |
---|---|---|
committer | Stefan Niedermann <info@niedermann.it> | 2020-10-28 17:09:09 +0300 |
commit | db3fe7aa94bed2d466a493abd073378601242db3 (patch) | |
tree | d6a6ba144a7d7548ff9ca191aebe2618d376926b | |
parent | 9f066ffc3314b35949e544d3cf76c33c096f2ce5 (diff) |
Use ColorUtils from android-commons where possible
14 files changed, 131 insertions, 312 deletions
diff --git a/app/build.gradle b/app/build.gradle index 32594a2a..fa5efabe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -66,7 +66,7 @@ dependencies { implementation "com.github.nextcloud:Android-SingleSignOn:0.5.3" implementation 'com.github.stefan-niedermann.nextcloud-commons:sso-glide:1.2.0' implementation 'com.github.stefan-niedermann.nextcloud-commons:exception:1.2.0' - implementation 'com.github.stefan-niedermann:android-commons:0.0.9' + implementation 'com.github.stefan-niedermann:android-commons:0.1.0' // Glide implementation 'com.github.bumptech.glide:glide:4.11.0' diff --git a/app/src/androidTest/java/it/niedermann/owncloud/notes/persistence/util/ColorUtilTest.java b/app/src/androidTest/java/it/niedermann/owncloud/notes/persistence/util/ColorUtilTest.java deleted file mode 100644 index 84f2cc91..00000000 --- a/app/src/androidTest/java/it/niedermann/owncloud/notes/persistence/util/ColorUtilTest.java +++ /dev/null @@ -1,126 +0,0 @@ -package it.niedermann.owncloud.notes.persistence.util; - -import android.graphics.Color; - -import androidx.annotation.ColorInt; -import androidx.core.util.Pair; -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; - -import java.util.ArrayList; -import java.util.List; - -import it.niedermann.owncloud.notes.shared.util.ColorUtil; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -@RunWith(AndroidJUnit4.class) -public class ColorUtilTest { - - @ColorInt - private static final int[] DARK_COLORS = new int[]{ - Color.BLACK, - Color.parseColor("#0082C9"), // "Nextcloud-Blue" - Color.parseColor("#007676") - }; - - @ColorInt - private static final int[] LIGHT_COLORS = new int[]{ - Color.WHITE, - Color.YELLOW - }; - - @Test - public void testGetForegroundColorForBackgroundColor() { - for (@ColorInt int color : DARK_COLORS) { - assertEquals( - "Expect foreground color for " + String.format("#%06X", (0xFFFFFF & color)) + " to be " + String.format("#%06X", (0xFFFFFF & Color.WHITE)), - Color.WHITE, ColorUtil.getForegroundColorForBackgroundColor(color) - ); - } - for (@ColorInt int color : LIGHT_COLORS) { - assertEquals( - "Expect foreground color for " + String.format("#%06X", (0xFFFFFF & color)) + " to be " + String.format("#%06X", (0xFFFFFF & Color.BLACK)), - Color.BLACK, ColorUtil.getForegroundColorForBackgroundColor(color) - ); - } - assertEquals( - "Expect foreground color for " + String.format("#%06X", (0xFFFFFF & Color.TRANSPARENT)) + " to be " + String.format("#%06X", (0xFFFFFF & Color.BLACK)), - Color.BLACK, ColorUtil.getForegroundColorForBackgroundColor(Color.TRANSPARENT) - ); - } - - @Test - public void testIsColorDark() { - for (@ColorInt int color : DARK_COLORS) { - assertTrue( - "Expect " + String.format("#%06X", (0xFFFFFF & color)) + " to be a dark color", - ColorUtil.isColorDark(color) - ); - } - for (@ColorInt int color : LIGHT_COLORS) { - assertFalse( - "Expect " + String.format("#%06X", (0xFFFFFF & color)) + " to be a light color", - ColorUtil.isColorDark(color) - ); - } - } - - @Test - public void testContrastRatioIsSufficient() { - final List<Pair<Integer, Integer>> sufficientContrastColorPairs = new ArrayList<>(); - sufficientContrastColorPairs.add(new Pair<>(Color.BLACK, Color.WHITE)); - sufficientContrastColorPairs.add(new Pair<>(Color.WHITE, Color.parseColor("#0082C9"))); - - for (Pair<Integer, Integer> colorPair : sufficientContrastColorPairs) { - assert colorPair.first != null; - assert colorPair.second != null; - assertTrue( - "Expect contrast between " + String.format("#%06X", (0xFFFFFF & colorPair.first)) + " and " + String.format("#%06X", (0xFFFFFF & colorPair.second)) + " to be sufficient", - ColorUtil.contrastRatioIsSufficient(colorPair.first, colorPair.second) - ); - } - - final List<Pair<Integer, Integer>> insufficientContrastColorPairs = new ArrayList<>(); - insufficientContrastColorPairs.add(new Pair<>(Color.WHITE, Color.WHITE)); - insufficientContrastColorPairs.add(new Pair<>(Color.BLACK, Color.BLACK)); - - for (Pair<Integer, Integer> colorPair : insufficientContrastColorPairs) { - assert colorPair.first != null; - assert colorPair.second != null; - assertFalse( - "Expect contrast between " + String.format("#%06X", (0xFFFFFF & colorPair.first)) + " and " + String.format("#%06X", (0xFFFFFF & colorPair.second)) + " to be insufficient", - ColorUtil.contrastRatioIsSufficient(colorPair.first, colorPair.second) - ); - } - } - - @Rule - public final ExpectedException exception = ExpectedException.none(); - - @Test - public void testGetCleanHexaColorString() { - final List<Pair<String, String>> validColors = new ArrayList<>(); - validColors.add(new Pair<>("#0082C9", "#0082C9")); - validColors.add(new Pair<>("0082C9", "#0082C9")); - validColors.add(new Pair<>("#CCC", "#CCCCCC")); - validColors.add(new Pair<>("ccc", "#cccccc")); - validColors.add(new Pair<>("af0", "#aaff00")); - validColors.add(new Pair<>("#af0", "#aaff00")); - for (Pair<String, String> color : validColors) { - assertEquals("Expect " + color.first + " to be cleaned up to " + color.second, color.second, ColorUtil.formatColorToParsableHexString(color.first)); - } - - final String[] invalidColors = new String[]{null, "", "cc", "c", "#a", "#55L", "55L"}; - for (String color : invalidColors) { - exception.expect(IllegalArgumentException.class); - ColorUtil.formatColorToParsableHexString(color); - } - } -} diff --git a/app/src/androidTest/java/it/niedermann/owncloud/notes/persistence/util/NotesColorUtilTest.java b/app/src/androidTest/java/it/niedermann/owncloud/notes/persistence/util/NotesColorUtilTest.java new file mode 100644 index 00000000..324bc37d --- /dev/null +++ b/app/src/androidTest/java/it/niedermann/owncloud/notes/persistence/util/NotesColorUtilTest.java @@ -0,0 +1,49 @@ +package it.niedermann.owncloud.notes.persistence.util; + +import android.graphics.Color; + +import androidx.core.util.Pair; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.ArrayList; +import java.util.List; + +import it.niedermann.owncloud.notes.shared.util.NotesColorUtil; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +@RunWith(AndroidJUnit4.class) +public class NotesColorUtilTest { + @Test + public void testContrastRatioIsSufficient() { + final List<Pair<Integer, Integer>> sufficientContrastColorPairs = new ArrayList<>(); + sufficientContrastColorPairs.add(new Pair<>(Color.BLACK, Color.WHITE)); + sufficientContrastColorPairs.add(new Pair<>(Color.WHITE, Color.parseColor("#0082C9"))); + + for (Pair<Integer, Integer> colorPair : sufficientContrastColorPairs) { + assert colorPair.first != null; + assert colorPair.second != null; + assertTrue( + "Expect contrast between " + String.format("#%06X", (0xFFFFFF & colorPair.first)) + " and " + String.format("#%06X", (0xFFFFFF & colorPair.second)) + " to be sufficient", + NotesColorUtil.contrastRatioIsSufficient(colorPair.first, colorPair.second) + ); + } + + final List<Pair<Integer, Integer>> insufficientContrastColorPairs = new ArrayList<>(); + insufficientContrastColorPairs.add(new Pair<>(Color.WHITE, Color.WHITE)); + insufficientContrastColorPairs.add(new Pair<>(Color.BLACK, Color.BLACK)); + + for (Pair<Integer, Integer> colorPair : insufficientContrastColorPairs) { + assert colorPair.first != null; + assert colorPair.second != null; + assertFalse( + "Expect contrast between " + String.format("#%06X", (0xFFFFFF & colorPair.first)) + " and " + String.format("#%06X", (0xFFFFFF & colorPair.second)) + " to be insufficient", + NotesColorUtil.contrastRatioIsSufficient(colorPair.first, colorPair.second) + ); + } + } +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentLicenseTab.java b/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentLicenseTab.java index 41f8266a..da8cbbd4 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentLicenseTab.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/about/AboutFragmentLicenseTab.java @@ -12,11 +12,11 @@ import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.core.graphics.drawable.DrawableCompat; +import it.niedermann.android.util.ColorUtil; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandedFragment; import it.niedermann.owncloud.notes.branding.BrandingUtil; import it.niedermann.owncloud.notes.databinding.FragmentAboutLicenseTabBinding; -import it.niedermann.owncloud.notes.shared.util.ColorUtil; import it.niedermann.owncloud.notes.shared.util.SupportUtil; public class AboutFragmentLicenseTab extends BrandedFragment { @@ -39,6 +39,6 @@ public class AboutFragmentLicenseTab extends BrandedFragment { public void applyBrand(int mainColor, int textColor) { @ColorInt final int finalMainColor = BrandingUtil.getSecondaryForegroundColorDependingOnTheme(requireContext(), mainColor); DrawableCompat.setTintList(binding.aboutAppLicenseButton.getBackground(), ColorStateList.valueOf(finalMainColor)); - binding.aboutAppLicenseButton.setTextColor(ColorUtil.getForegroundColorForBackgroundColor(finalMainColor)); + binding.aboutAppLicenseButton.setTextColor(ColorUtil.INSTANCE.getForegroundColorForBackgroundColor(finalMainColor)); } }
\ No newline at end of file diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSnackbar.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSnackbar.java index 80a5d91a..aabd3f04 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSnackbar.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandedSnackbar.java @@ -8,7 +8,7 @@ import androidx.annotation.StringRes; import com.google.android.material.snackbar.Snackbar; -import it.niedermann.owncloud.notes.shared.util.ColorUtil; +import it.niedermann.android.util.ColorUtil; public class BrandedSnackbar { @@ -17,7 +17,7 @@ public class BrandedSnackbar { final Snackbar snackbar = Snackbar.make(view, text, duration); if (BrandingUtil.isBrandingEnabled(view.getContext())) { int color = BrandingUtil.readBrandMainColor(view.getContext()); - snackbar.setActionTextColor(ColorUtil.isColorDark(color) ? Color.WHITE : color); + snackbar.setActionTextColor(ColorUtil.INSTANCE.isColorDark(color) ? Color.WHITE : color); } return snackbar; } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java index 661b956d..98a99b31 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/branding/BrandingUtil.java @@ -24,7 +24,7 @@ import it.niedermann.android.sharedpreferences.SharedPreferenceIntLiveData; import it.niedermann.owncloud.notes.NotesApplication; import it.niedermann.owncloud.notes.R; -import static it.niedermann.owncloud.notes.shared.util.ColorUtil.contrastRatioIsSufficient; +import static it.niedermann.owncloud.notes.shared.util.NotesColorUtil.contrastRatioIsSufficient; public class BrandingUtil { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java index c3d10339..63977ff1 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java @@ -33,6 +33,7 @@ import com.nextcloud.android.sso.model.SingleSignOnAccount; import java.util.ArrayList; import java.util.Calendar; +import it.niedermann.android.util.ColorUtil; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.accountpicker.AccountPickerDialogFragment; import it.niedermann.owncloud.notes.branding.BrandedFragment; @@ -47,15 +48,14 @@ import it.niedermann.owncloud.notes.persistence.entity.NoteWithCategory; import it.niedermann.owncloud.notes.shared.model.ApiVersion; import it.niedermann.owncloud.notes.shared.model.DBStatus; import it.niedermann.owncloud.notes.shared.model.ISyncCallback; -import it.niedermann.owncloud.notes.shared.util.ColorUtil; import it.niedermann.owncloud.notes.shared.util.NoteUtil; +import it.niedermann.owncloud.notes.shared.util.NotesColorUtil; import it.niedermann.owncloud.notes.shared.util.ShareUtil; import static androidx.core.content.pm.ShortcutManagerCompat.isRequestPinShortcutSupported; import static it.niedermann.owncloud.notes.NotesApplication.isDarkThemeActive; import static it.niedermann.owncloud.notes.branding.BrandingUtil.tintMenuIcon; import static it.niedermann.owncloud.notes.edit.EditNoteActivity.ACTION_SHORTCUT; -import static it.niedermann.owncloud.notes.shared.util.ColorUtil.isColorDark; import static java.lang.Boolean.TRUE; public abstract class BaseNoteFragment extends BrandedFragment implements CategoryDialogListener, EditTitleListener { @@ -369,28 +369,28 @@ public abstract class BaseNoteFragment extends BrandedFragment implements Catego @ColorInt protected static int getTextHighlightBackgroundColor(@NonNull Context context, @ColorInt int mainColor, @ColorInt int colorPrimary, @ColorInt int colorAccent) { if (isDarkThemeActive(context)) { // Dark background - if (isColorDark(mainColor)) { // Dark brand color - if (ColorUtil.contrastRatioIsSufficient(mainColor, colorPrimary)) { // But also dark text + if (ColorUtil.INSTANCE.isColorDark(mainColor)) { // Dark brand color + if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorPrimary)) { // But also dark text return mainColor; } else { return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); } } else { // Light brand color - if (ColorUtil.contrastRatioIsSufficient(mainColor, colorAccent)) { // But also dark text + if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorAccent)) { // But also dark text return Color.argb(77, Color.red(mainColor), Color.green(mainColor), Color.blue(mainColor)); } else { return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); } } } else { // Light background - if (isColorDark(mainColor)) { // Dark brand color - if (ColorUtil.contrastRatioIsSufficient(mainColor, colorAccent)) { // But also dark text + if (ColorUtil.INSTANCE.isColorDark(mainColor)) { // Dark brand color + if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorAccent)) { // But also dark text return Color.argb(77, Color.red(mainColor), Color.green(mainColor), Color.blue(mainColor)); } else { return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); } } else { // Light brand color - if (ColorUtil.contrastRatioIsSufficient(mainColor, colorPrimary)) { // But also dark text + if (NotesColorUtil.contrastRatioIsSufficient(mainColor, colorPrimary)) { // But also dark text return mainColor; } else { return ContextCompat.getColor(context, R.color.defaultTextHighlightBackground); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java index 627de293..cae371d5 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/MainActivity.java @@ -93,7 +93,7 @@ import static it.niedermann.owncloud.notes.shared.model.ENavigationCategoryType. import static it.niedermann.owncloud.notes.shared.model.ENavigationCategoryType.FAVORITES; import static it.niedermann.owncloud.notes.shared.model.ENavigationCategoryType.RECENT; import static it.niedermann.owncloud.notes.shared.model.ENavigationCategoryType.UNCATEGORIZED; -import static it.niedermann.owncloud.notes.shared.util.ColorUtil.contrastRatioIsSufficient; +import static it.niedermann.owncloud.notes.shared.util.NotesColorUtil.contrastRatioIsSufficient; import static it.niedermann.owncloud.notes.shared.util.SSOUtil.askForNewAccount; public class MainActivity extends LockedActivity implements NoteClickListener, AccountPickerListener, AccountSwitcherListener, CategoryDialogFragment.CategoryDialogListener { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java b/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java index f8d259fa..4bbf05bd 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/main/items/NoteViewHolder.java @@ -27,19 +27,17 @@ import com.google.android.material.chip.Chip; import java.util.regex.Matcher; import java.util.regex.Pattern; +import it.niedermann.android.util.ColorUtil; import it.niedermann.owncloud.notes.NotesApplication; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandingUtil; -import it.niedermann.owncloud.notes.persistence.entity.Note; import it.niedermann.owncloud.notes.persistence.entity.NoteWithCategory; import it.niedermann.owncloud.notes.shared.model.DBStatus; import it.niedermann.owncloud.notes.shared.model.NoteClickListener; import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; -import static androidx.recyclerview.widget.ItemTouchHelper.Callback.getDefaultUIUtil; -import static it.niedermann.owncloud.notes.shared.util.ColorUtil.contrastRatioIsSufficient; -import static it.niedermann.owncloud.notes.shared.util.ColorUtil.isColorDark; +import static it.niedermann.owncloud.notes.shared.util.NotesColorUtil.contrastRatioIsSufficient; public abstract class NoteViewHolder extends RecyclerView.ViewHolder { @NonNull @@ -71,7 +69,7 @@ public abstract class NoteViewHolder extends RecyclerView.ViewHolder { @ColorInt int categoryBackground; if (isDarkThemeActive) { - if (isColorDark(mainColor)) { + if (ColorUtil.INSTANCE.isColorDark(mainColor)) { if (contrastRatioIsSufficient(mainColor, Color.BLACK)) { categoryBackground = mainColor; categoryForeground = Color.WHITE; @@ -85,7 +83,7 @@ public abstract class NoteViewHolder extends RecyclerView.ViewHolder { } } else { categoryForeground = Color.BLACK; - if (isColorDark(mainColor) || contrastRatioIsSufficient(mainColor, Color.WHITE)) { + if (ColorUtil.INSTANCE.isColorDark(mainColor) || contrastRatioIsSufficient(mainColor, Color.WHITE)) { categoryBackground = mainColor; } else { categoryBackground = Color.BLACK; diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_19_20.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_19_20.java index 9f749d86..b213d8a1 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_19_20.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_19_20.java @@ -11,7 +11,7 @@ import androidx.room.RoomDatabase; import androidx.room.migration.Migration; import androidx.sqlite.db.SupportSQLiteDatabase; -import it.niedermann.owncloud.notes.shared.util.ColorUtil; +import it.niedermann.android.util.ColorUtil; public class Migration_19_20 extends Migration { @@ -79,13 +79,13 @@ public class Migration_19_20 extends Migration { values.put("MODIFIED", tmpAccountCursor.getLong(5)); values.put("APIVERSION", tmpAccountCursor.getString(6)); try { - values.put("COLOR", Color.parseColor(ColorUtil.formatColorToParsableHexString(tmpAccountCursor.getString(7)))); + values.put("COLOR", Color.parseColor(ColorUtil.INSTANCE.formatColorToParsableHexString(tmpAccountCursor.getString(7)))); } catch (Exception e) { e.printStackTrace(); values.put("COLOR", -16743735); } try { - values.put("TEXTCOLOR", Color.parseColor(ColorUtil.formatColorToParsableHexString(tmpAccountCursor.getString(8)))); + values.put("TEXTCOLOR", Color.parseColor(ColorUtil.INSTANCE.formatColorToParsableHexString(tmpAccountCursor.getString(8)))); } catch (Exception e) { e.printStackTrace(); values.put("TEXTCOLOR", -16777216); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/model/Capabilities.java b/app/src/main/java/it/niedermann/owncloud/notes/shared/model/Capabilities.java index 21f5b6ac..77eed718 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/shared/model/Capabilities.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/model/Capabilities.java @@ -13,7 +13,7 @@ import com.nextcloud.android.sso.exceptions.NextcloudHttpRequestFailedException; import org.json.JSONException; import org.json.JSONObject; -import it.niedermann.owncloud.notes.shared.util.ColorUtil; +import it.niedermann.android.util.ColorUtil; import static java.net.HttpURLConnection.HTTP_UNAVAILABLE; @@ -72,14 +72,14 @@ public class Capabilities { final JSONObject theming = capabilities.getJSONObject(JSON_OCS_DATA_CAPABILITIES_THEMING); if (theming.has(JSON_OCS_DATA_CAPABILITIES_THEMING_COLOR)) { try { - this.color = Color.parseColor(ColorUtil.formatColorToParsableHexString(theming.getString(JSON_OCS_DATA_CAPABILITIES_THEMING_COLOR))); + this.color = Color.parseColor(ColorUtil.INSTANCE.formatColorToParsableHexString(theming.getString(JSON_OCS_DATA_CAPABILITIES_THEMING_COLOR))); } catch (Exception e) { e.printStackTrace(); } } if (theming.has(JSON_OCS_DATA_CAPABILITIES_THEMING_COLOR_TEXT)) { try { - this.textColor = Color.parseColor(ColorUtil.formatColorToParsableHexString(theming.getString(JSON_OCS_DATA_CAPABILITIES_THEMING_COLOR_TEXT))); + this.textColor = Color.parseColor(ColorUtil.INSTANCE.formatColorToParsableHexString(theming.getString(JSON_OCS_DATA_CAPABILITIES_THEMING_COLOR_TEXT))); } catch (Exception e) { e.printStackTrace(); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/ColorUtil.java b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/ColorUtil.java deleted file mode 100644 index a7f1b566..00000000 --- a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/ColorUtil.java +++ /dev/null @@ -1,154 +0,0 @@ -package it.niedermann.owncloud.notes.shared.util; - -import android.graphics.Color; - -import androidx.annotation.ColorInt; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.util.Pair; - -import java.util.HashMap; -import java.util.Map; - -public final class ColorUtil { - - private static final Map<ColorPair, Boolean> CONTRAST_RATIO_SUFFICIENT_CACHE = new HashMap<>(); - private static final Map<Integer, Integer> FOREGROUND_CACHE = new HashMap<>(); - private static final Map<Integer, Boolean> IS_DARK_COLOR_CACHE = new HashMap<>(); - - private ColorUtil() { - } - - @ColorInt - public static int getForegroundColorForBackgroundColor(@ColorInt int color) { - Integer ret = FOREGROUND_CACHE.get(color); - if (ret == null) { - if (Color.TRANSPARENT == color) - ret = Color.BLACK; - else if (isColorDark(color)) - ret = Color.WHITE; - else - ret = Color.BLACK; - - FOREGROUND_CACHE.put(color, ret); - } - return ret; - } - - public static boolean isColorDark(@ColorInt int color) { - Boolean ret = IS_DARK_COLOR_CACHE.get(color); - if (ret == null) { - ret = getBrightness(color) < 200; - IS_DARK_COLOR_CACHE.put(color, ret); - } - return ret; - } - - private static int getBrightness(@ColorInt int color) { - final int[] rgb = {Color.red(color), Color.green(color), Color.blue(color)}; - - return (int) Math.sqrt(rgb[0] * rgb[0] * .241 + rgb[1] - * rgb[1] * .691 + rgb[2] * rgb[2] * .068); - } - - // --------------------------------------------------- - // Based on https://github.com/LeaVerou/contrast-ratio - // --------------------------------------------------- - - public static boolean contrastRatioIsSufficient(@ColorInt int colorOne, @ColorInt int colorTwo) { - ColorPair key = new ColorPair(colorOne, colorTwo); - Boolean ret = CONTRAST_RATIO_SUFFICIENT_CACHE.get(key); - if (ret == null) { - ret = getContrastRatio(colorOne, colorTwo) > 3d; - CONTRAST_RATIO_SUFFICIENT_CACHE.put(key, ret); - return ret; - } - return ret; - } - - private static double getContrastRatio(@ColorInt int colorOne, @ColorInt int colorTwo) { - final double lum1 = getLuminanace(colorOne); - final double lum2 = getLuminanace(colorTwo); - final double brightest = Math.max(lum1, lum2); - final double darkest = Math.min(lum1, lum2); - return (brightest + 0.05) / (darkest + 0.05); - } - - private static double getLuminanace(@ColorInt int color) { - final int[] rgb = {Color.red(color), Color.green(color), Color.blue(color)}; - return getSubcolorLuminance(rgb[0]) * 0.2126 + getSubcolorLuminance(rgb[1]) * 0.7152 + getSubcolorLuminance(rgb[2]) * 0.0722; - } - - private static double getSubcolorLuminance(@ColorInt int color) { - final double value = color / 255d; - return value <= 0.03928 - ? value / 12.92 - : Math.pow((value + 0.055) / 1.055, 2.4); - } - - private static class ColorPair extends Pair<Integer, Integer> { - - private ColorPair(@Nullable Integer first, @Nullable Integer second) { - super(first, second); - } - - @SuppressWarnings({"EqualsWhichDoesntCheckParameterClass", "NumberEquality"}) - @Override - public boolean equals(Object o) { - final ColorPair colorPair = (ColorPair) o; - if (first != colorPair.first) return false; - return second == colorPair.second; - } - - @SuppressWarnings("ConstantConditions") - @Override - public int hashCode() { - int result = first; - result = 31 * result + second; - return result; - } - } - - /** - * @return well formatted string starting with a hash followed by 6 hex numbers that is parsable by {@link Color#parseColor(String)}. - */ - public static String formatColorToParsableHexString(String input) { - if (input == null) { - throw new IllegalArgumentException("input color string is null"); - } - if (isParsableValidHexColorString(input)) { - return input; - } - final char[] chars = input.replaceAll("#", "").toCharArray(); - final StringBuilder sb = new StringBuilder(7).append("#"); - if (chars.length == 6) { - sb.append(chars); - } else if (chars.length == 3) { - for (char c : chars) { - sb.append(c).append(c); - } - } else { - throw new IllegalArgumentException("unparsable color string: \"" + input + "\""); - } - final String formattedHexColor = sb.toString(); - if (isParsableValidHexColorString(formattedHexColor)) { - return formattedHexColor; - } else { - throw new IllegalArgumentException("\"" + input + "\" is not a valid color string. Result of tried normalizing: " + formattedHexColor); - } - } - - /** - * Checking for {@link Color#parseColor(String)} being able to parse the input is the important part because we don't know the implementation and rely on it to be able to parse the color. - * - * @return true, if the input starts with a hash followed by 6 characters of hex numbers and is parsable by {@link Color#parseColor(String)}. - */ - private static boolean isParsableValidHexColorString(@NonNull String input) { - try { - Color.parseColor(input); - return input.matches("#[a-fA-F0-9]{6}"); - } catch (Exception e) { - return false; - } - } -} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/DisplayUtils.java b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/DisplayUtils.java index 05921aee..68e6ee7c 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/DisplayUtils.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/DisplayUtils.java @@ -37,6 +37,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import it.niedermann.android.util.ColorUtil; import it.niedermann.owncloud.notes.NotesApplication; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.branding.BrandingUtil; @@ -44,8 +45,6 @@ import it.niedermann.owncloud.notes.main.navigation.NavigationAdapter; import it.niedermann.owncloud.notes.main.navigation.NavigationItem; import it.niedermann.owncloud.notes.persistence.entity.CategoryWithNotesCount; -import static it.niedermann.owncloud.notes.shared.util.ColorUtil.isColorDark; - public class DisplayUtils { private DisplayUtils() { @@ -104,7 +103,7 @@ public class DisplayUtils { public void updateDrawState(TextPaint tp) { if (current) { if (NotesApplication.isDarkThemeActive(context)) { - if (isColorDark(mainColor)) { + if (ColorUtil.INSTANCE.isColorDark(mainColor)) { tp.bgColor = Color.WHITE; tp.setColor(mainColor); } else { @@ -112,11 +111,11 @@ public class DisplayUtils { tp.setColor(Color.BLACK); } } else { - if (isColorDark(mainColor)) { + if (ColorUtil.INSTANCE.isColorDark(mainColor)) { tp.bgColor = mainColor; tp.setColor(Color.WHITE); } else { - if (ColorUtil.contrastRatioIsSufficient(mainColor, highlightColor)) { + if (NotesColorUtil.contrastRatioIsSufficient(mainColor, highlightColor)) { tp.bgColor = highlightColor; } else { tp.bgColor = Color.BLACK; diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/NotesColorUtil.java b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/NotesColorUtil.java new file mode 100644 index 00000000..3eb40e97 --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/NotesColorUtil.java @@ -0,0 +1,53 @@ +package it.niedermann.owncloud.notes.shared.util; + +import androidx.annotation.ColorInt; +import androidx.annotation.Nullable; +import androidx.core.util.Pair; + +import java.util.HashMap; +import java.util.Map; + +import it.niedermann.android.util.ColorUtil; + +public final class NotesColorUtil { + + private static final Map<ColorPair, Boolean> CONTRAST_RATIO_SUFFICIENT_CACHE = new HashMap<>(); + + // --------------------------------------------------- + // Based on https://github.com/LeaVerou/contrast-ratio + // --------------------------------------------------- + + public static boolean contrastRatioIsSufficient(@ColorInt int colorOne, @ColorInt int colorTwo) { + ColorPair key = new ColorPair(colorOne, colorTwo); + Boolean ret = CONTRAST_RATIO_SUFFICIENT_CACHE.get(key); + if (ret == null) { + ret = ColorUtil.INSTANCE.getContrastRatio(colorOne, colorTwo) > 3d; + CONTRAST_RATIO_SUFFICIENT_CACHE.put(key, ret); + return ret; + } + return ret; + } + + private static class ColorPair extends Pair<Integer, Integer> { + + private ColorPair(@Nullable Integer first, @Nullable Integer second) { + super(first, second); + } + + @SuppressWarnings({"EqualsWhichDoesntCheckParameterClass", "NumberEquality"}) + @Override + public boolean equals(Object o) { + final ColorPair colorPair = (ColorPair) o; + if (first != colorPair.first) return false; + return second == colorPair.second; + } + + @SuppressWarnings("ConstantConditions") + @Override + public int hashCode() { + int result = first; + result = 31 * result + second; + return result; + } + } +} |