diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/base/AbsSlidingMusicPanelActivity.java b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/base/AbsSlidingMusicPanelActivity.java
index 99d26cf4..f859c998 100644
--- a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/base/AbsSlidingMusicPanelActivity.java
+++ b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/base/AbsSlidingMusicPanelActivity.java
@@ -722,16 +722,12 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
private void updateShuffleState() {
switch (MusicPlayerRemote.getShuffleMode()) {
case MusicService.SHUFFLE_MODE_SHUFFLE:
- int activatedColor = colorPlaybackControls
- ? getFixedShuffleRepeatButtonColor(lastPlaybackControlsColor)
- : ThemeSingleton.get().positiveColor.getDefaultColor();
shuffleButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_shuffle_white_36dp,
- activatedColor));
+ getActivatedIconColor()));
break;
default:
- int deactivatedColor = ColorUtil.resolveColor(this, android.R.attr.textColorSecondary);
shuffleButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_shuffle_white_36dp,
- deactivatedColor));
+ getDeactivatedIconColor()));
break;
}
}
@@ -747,34 +743,43 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
}
private void updateRepeatState() {
- int activatedColor = colorPlaybackControls
- ? getFixedShuffleRepeatButtonColor(lastPlaybackControlsColor)
- : ThemeSingleton.get().positiveColor.getDefaultColor();
switch (MusicPlayerRemote.getRepeatMode()) {
case MusicService.REPEAT_MODE_ALL:
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_white_36dp,
- activatedColor));
+ getActivatedIconColor()));
break;
case MusicService.REPEAT_MODE_THIS:
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_one_white_36dp,
- activatedColor));
+ getActivatedIconColor()));
break;
default:
- int deactivatedColor = ColorUtil.resolveColor(this, android.R.attr.textColorSecondary);
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_white_36dp,
- deactivatedColor));
+ getDeactivatedIconColor()));
break;
}
}
+ private int getActivatedIconColor() {
+ if (colorPlaybackControls) {
+ return ensureActivatedColorVisibleIfNecessary(lastPlaybackControlsColor);
+ } else {
+ return ThemeSingleton.get().positiveColor.getDefaultColor();
+ }
+ }
+
+ private int getDeactivatedIconColor() {
+ return ColorUtil.resolveColor(this, android.R.attr.textColorSecondary);
+ }
+
/**
- * Checks whether the default color and the activated color are similar. If true, returns a darker
- * activated color. Else, returns the given color as-is.
+ * @return If the activated color wont have enough difference to the deactivated color Color.WHITE / Color.BLACK (depending on the theme),
+ * else the unmodified accentColor.
*/
- private int getFixedShuffleRepeatButtonColor(int activatedColor) {
- if (ColorUtil.calculateColorDistance(activatedColor,
- ColorUtil.resolveColor(this, android.R.attr.textColorSecondary))) {
- return ColorUtil.shiftColor(activatedColor, 0.6f);
+ private int ensureActivatedColorVisibleIfNecessary(int activatedColor) {
+ // Not optimal, but much easier then computing the opaque deactivated color on the background color every time.
+ int preBlendedDeactivatedIconColor = ThemeSingleton.get().darkTheme ? Color.argb(255, 188, 188, 188) : Color.argb(255, 115, 115, 115);
+ if (ColorUtil.getColorDifference(activatedColor, preBlendedDeactivatedIconColor) <= 30d) {
+ return ThemeSingleton.get().darkTheme ? Color.WHITE : Color.BLACK;
}
return activatedColor;
}
diff --git a/app/src/main/java/com/kabouzeid/gramophone/util/ColorUtil.java b/app/src/main/java/com/kabouzeid/gramophone/util/ColorUtil.java
index 0945c2fe..dfa1e703 100644
--- a/app/src/main/java/com/kabouzeid/gramophone/util/ColorUtil.java
+++ b/app/src/main/java/com/kabouzeid/gramophone/util/ColorUtil.java
@@ -138,16 +138,91 @@ public class ColorUtil {
return backgroundColor;
}
+ public static int[] rgb2lab(int R, int G, int B) {
+ //http://www.brucelindbloom.com
+
+ float r, g, b, X, Y, Z, fx, fy, fz, xr, yr, zr;
+ float Ls, as, bs;
+ float eps = 216.f / 24389.f;
+ float k = 24389.f / 27.f;
+
+ float Xr = 0.964221f; // reference white D50
+ float Yr = 1.0f;
+ float Zr = 0.825211f;
+
+ // RGB to XYZ
+ r = R / 255.f; //R 0..1
+ g = G / 255.f; //G 0..1
+ b = B / 255.f; //B 0..1
+
+ // assuming sRGB (D65)
+ if (r <= 0.04045)
+ r = r / 12;
+ else
+ r = (float) Math.pow((r + 0.055) / 1.055, 2.4);
+
+ if (g <= 0.04045)
+ g = g / 12;
+ else
+ g = (float) Math.pow((g + 0.055) / 1.055, 2.4);
+
+ if (b <= 0.04045)
+ b = b / 12;
+ else
+ b = (float) Math.pow((b + 0.055) / 1.055, 2.4);
+
+
+ X = 0.436052025f * r + 0.385081593f * g + 0.143087414f * b;
+ Y = 0.222491598f * r + 0.71688606f * g + 0.060621486f * b;
+ Z = 0.013929122f * r + 0.097097002f * g + 0.71418547f * b;
+
+ // XYZ to Lab
+ xr = X / Xr;
+ yr = Y / Yr;
+ zr = Z / Zr;
+
+ if (xr > eps)
+ fx = (float) Math.pow(xr, 1 / 3.);
+ else
+ fx = (float) ((k * xr + 16.) / 116.);
+
+ if (yr > eps)
+ fy = (float) Math.pow(yr, 1 / 3.);
+ else
+ fy = (float) ((k * yr + 16.) / 116.);
+
+ if (zr > eps)
+ fz = (float) Math.pow(zr, 1 / 3.);
+ else
+ fz = (float) ((k * zr + 16.) / 116);
+
+ Ls = (116 * fy) - 16;
+ as = 500 * (fx - fy);
+ bs = 200 * (fy - fz);
+
+ int[] lab = new int[3];
+ lab[0] = (int) (2.55 * Ls + .5);
+ lab[1] = (int) (as + .5);
+ lab[2] = (int) (bs + .5);
+ return lab;
+ }
+
/**
- * Calculates the distance of two colors in 3D Space.
+ * Computes the difference between two RGB colors by converting them to the L*a*b scale and
+ * comparing them using the CIE76 algorithm { http://en.wikipedia.org/wiki/Color_difference#CIE76}
*
- * Taken from http://stackoverflow.com/a/1725535/984061
+ * @return > 23 corresponds to a JND (just noticeable difference)
*/
- public static boolean calculateColorDistance(int color1, int color2) {
- double red = Math.pow(Math.abs(Color.red(color2) - Color.red(color1)), 2);
- double green = Math.pow(Math.abs(Color.green(color2) - Color.green(color1)), 2);
- double blue = Math.pow(Math.abs(Color.blue(color2) - Color.blue(color1)), 2);
- double distance = red + green + blue;
- return distance < 55000;
+ public static double getColorDifference(int a, int b) {
+ int r1, g1, b1, r2, g2, b2;
+ r1 = Color.red(a);
+ g1 = Color.green(a);
+ b1 = Color.blue(a);
+ r2 = Color.red(b);
+ g2 = Color.green(b);
+ b2 = Color.blue(b);
+ int[] lab1 = rgb2lab(r1, g1, b1);
+ int[] lab2 = rgb2lab(r2, g2, b2);
+ return Math.sqrt(Math.pow(lab2[0] - lab1[0], 2) + Math.pow(lab2[1] - lab1[1], 2) + Math.pow(lab2[2] - lab1[2], 2));
}
}
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index cb438b07..8ae95aff 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -4,7 +4,7 @@
#ff4081
#3f51b5
- #424242
+ #616161
#212121
\ No newline at end of file
diff --git a/app/src/main/res/values/styles_parents.xml b/app/src/main/res/values/styles_parents.xml
index f3082c16..af03a3be 100644
--- a/app/src/main/res/values/styles_parents.xml
+++ b/app/src/main/res/values/styles_parents.xml
@@ -43,7 +43,7 @@
- @color/cardview_light_background
- - @color/grey_800
+ - @color/grey_700
- @color/md_divider_black
- @color/secondary_text_default_material_light