Replaced the algorithm for determining whether two colors are distinguishable. Merged some duplicated code into its own methods.
This commit is contained in:
parent
a1fb2d3c9d
commit
601c1d9489
4 changed files with 109 additions and 29 deletions
|
|
@ -722,16 +722,12 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
||||||
private void updateShuffleState() {
|
private void updateShuffleState() {
|
||||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
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,
|
shuffleButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_shuffle_white_36dp,
|
||||||
activatedColor));
|
getActivatedIconColor()));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
int deactivatedColor = ColorUtil.resolveColor(this, android.R.attr.textColorSecondary);
|
|
||||||
shuffleButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_shuffle_white_36dp,
|
shuffleButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_shuffle_white_36dp,
|
||||||
deactivatedColor));
|
getDeactivatedIconColor()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -747,34 +743,43 @@ public abstract class AbsSlidingMusicPanelActivity extends AbsMusicServiceActivi
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateRepeatState() {
|
private void updateRepeatState() {
|
||||||
int activatedColor = colorPlaybackControls
|
|
||||||
? getFixedShuffleRepeatButtonColor(lastPlaybackControlsColor)
|
|
||||||
: ThemeSingleton.get().positiveColor.getDefaultColor();
|
|
||||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||||
case MusicService.REPEAT_MODE_ALL:
|
case MusicService.REPEAT_MODE_ALL:
|
||||||
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_white_36dp,
|
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_white_36dp,
|
||||||
activatedColor));
|
getActivatedIconColor()));
|
||||||
break;
|
break;
|
||||||
case MusicService.REPEAT_MODE_THIS:
|
case MusicService.REPEAT_MODE_THIS:
|
||||||
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_one_white_36dp,
|
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_one_white_36dp,
|
||||||
activatedColor));
|
getActivatedIconColor()));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
int deactivatedColor = ColorUtil.resolveColor(this, android.R.attr.textColorSecondary);
|
|
||||||
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_white_36dp,
|
repeatButton.setImageDrawable(Util.getTintedDrawable(this, R.drawable.ic_repeat_white_36dp,
|
||||||
deactivatedColor));
|
getDeactivatedIconColor()));
|
||||||
break;
|
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
|
* @return If the activated color wont have enough difference to the deactivated color Color.WHITE / Color.BLACK (depending on the theme),
|
||||||
* activated color. Else, returns the given color as-is.
|
* else the unmodified accentColor.
|
||||||
*/
|
*/
|
||||||
private int getFixedShuffleRepeatButtonColor(int activatedColor) {
|
private int ensureActivatedColorVisibleIfNecessary(int activatedColor) {
|
||||||
if (ColorUtil.calculateColorDistance(activatedColor,
|
// Not optimal, but much easier then computing the opaque deactivated color on the background color every time.
|
||||||
ColorUtil.resolveColor(this, android.R.attr.textColorSecondary))) {
|
int preBlendedDeactivatedIconColor = ThemeSingleton.get().darkTheme ? Color.argb(255, 188, 188, 188) : Color.argb(255, 115, 115, 115);
|
||||||
return ColorUtil.shiftColor(activatedColor, 0.6f);
|
if (ColorUtil.getColorDifference(activatedColor, preBlendedDeactivatedIconColor) <= 30d) {
|
||||||
|
return ThemeSingleton.get().darkTheme ? Color.WHITE : Color.BLACK;
|
||||||
}
|
}
|
||||||
return activatedColor;
|
return activatedColor;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -138,16 +138,91 @@ public class ColorUtil {
|
||||||
return backgroundColor;
|
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) {
|
public static double getColorDifference(int a, int b) {
|
||||||
double red = Math.pow(Math.abs(Color.red(color2) - Color.red(color1)), 2);
|
int r1, g1, b1, r2, g2, b2;
|
||||||
double green = Math.pow(Math.abs(Color.green(color2) - Color.green(color1)), 2);
|
r1 = Color.red(a);
|
||||||
double blue = Math.pow(Math.abs(Color.blue(color2) - Color.blue(color1)), 2);
|
g1 = Color.green(a);
|
||||||
double distance = red + green + blue;
|
b1 = Color.blue(a);
|
||||||
return distance < 55000;
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<color name="pink_A200">#ff4081</color>
|
<color name="pink_A200">#ff4081</color>
|
||||||
<color name="indigo_500">#3f51b5</color>
|
<color name="indigo_500">#3f51b5</color>
|
||||||
|
|
||||||
<color name="grey_800">#424242</color>
|
<color name="grey_700">#616161</color>
|
||||||
<color name="grey_900">#212121</color>
|
<color name="grey_900">#212121</color>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
<item name="cardBackgroundColor">@color/cardview_light_background</item>
|
<item name="cardBackgroundColor">@color/cardview_light_background</item>
|
||||||
|
|
||||||
<item name="default_bar_color">@color/grey_800</item>
|
<item name="default_bar_color">@color/grey_700</item>
|
||||||
|
|
||||||
<item name="divider_color">@color/md_divider_black</item>
|
<item name="divider_color">@color/md_divider_black</item>
|
||||||
<item name="icon_color">@color/secondary_text_default_material_light</item>
|
<item name="icon_color">@color/secondary_text_default_material_light</item>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue