UIDefaultsLoader: added fadein(), fadeout(), fade() and spin() color functions (inspired by Less CSS)

This commit is contained in:
Karl Tauber
2020-11-19 11:31:38 +01:00
parent 8b8ed0b9ff
commit 0101171159
9 changed files with 135 additions and 20 deletions

View File

@@ -586,13 +586,17 @@ class UIDefaultsLoader
case "darken": return parseColorHSLIncreaseDecrease( 2, false, params, resolver, reportError );
case "saturate": return parseColorHSLIncreaseDecrease( 1, true, params, resolver, reportError );
case "desaturate": return parseColorHSLIncreaseDecrease( 1, false, params, resolver, reportError );
case "fadein": return parseColorHSLIncreaseDecrease( 3, true, params, resolver, reportError );
case "fadeout": return parseColorHSLIncreaseDecrease( 3, false, params, resolver, reportError );
case "fade": return parseColorFade( params, resolver, reportError );
case "spin": return parseColorSpin( params, resolver, reportError );
}
throw new IllegalArgumentException( "unknown color function '" + value + "'" );
}
/**
* Syntax: rgb(red,green,blue) or rgba(red,green,blue,alpha) or rgba(color,alpha)
* Syntax: rgb(red,green,blue) or rgba(red,green,blue,alpha)
* - red: an integer 0-255 or a percentage 0-100%
* - green: an integer 0-255 or a percentage 0-100%
* - blue: an integer 0-255 or a percentage 0-100%
@@ -603,6 +607,8 @@ class UIDefaultsLoader
{
if( hasAlpha && params.size() == 2 ) {
// syntax rgba(color,alpha), which allows adding alpha to any color
// NOTE: this syntax is deprecated
// use fade(color,alpha) instead
String colorStr = params.get( 0 );
int alpha = parseInteger( params.get( 1 ), 0, 255, true );
@@ -639,7 +645,8 @@ class UIDefaultsLoader
/**
* Syntax: lighten(color,amount[,options]) or darken(color,amount[,options]) or
* saturate(color,amount[,options]) or desaturate(color,amount[,options])
* saturate(color,amount[,options]) or desaturate(color,amount[,options]) or
* fadein(color,amount[,options]) or fadeout(color,amount[,options])
* - color: a color (e.g. #f00) or a color function
* - amount: percentage 0-100%
* - options: [relative] [autoInverse] [noAutoInverse] [lazy] [derived]
@@ -679,6 +686,59 @@ class UIDefaultsLoader
};
}
// parse base color, apply function and create derived color
return parseFunctionBaseColor( colorStr, function, derived, resolver, reportError );
}
/**
* Syntax: fade(color,amount[,options])
* - color: a color (e.g. #f00) or a color function
* - amount: percentage 0-100%
* - options: [derived]
*/
private static Object parseColorFade( List<String> params, Function<String, String> resolver, boolean reportError ) {
String colorStr = params.get( 0 );
int amount = parsePercentage( params.get( 1 ) );
boolean derived = false;
if( params.size() > 2 ) {
String options = params.get( 2 );
derived = options.contains( "derived" );
}
// create function
ColorFunction function = new ColorFunctions.Fade( amount );
// parse base color, apply function and create derived color
return parseFunctionBaseColor( colorStr, function, derived, resolver, reportError );
}
/**
* Syntax: spin(color,angle[,options])
* - color: a color (e.g. #f00) or a color function
* - angle: number of degrees to rotate
* - options: [derived]
*/
private static Object parseColorSpin( List<String> params, Function<String, String> resolver, boolean reportError ) {
String colorStr = params.get( 0 );
int amount = parseInteger( params.get( 1 ), true );
boolean derived = false;
if( params.size() > 2 ) {
String options = params.get( 2 );
derived = options.contains( "derived" );
}
// create function
ColorFunction function = new ColorFunctions.HSLIncreaseDecrease( 0, true, amount, false, false );
// parse base color, apply function and create derived color
return parseFunctionBaseColor( colorStr, function, derived, resolver, reportError );
}
private static Object parseFunctionBaseColor( String colorStr, ColorFunction function,
boolean derived, Function<String, String> resolver, boolean reportError )
{
// parse base color
String resolvedColorStr = resolver.apply( colorStr );
ColorUIResource baseColor = (ColorUIResource) parseColorOrFunction( resolvedColorStr, resolver, reportError );

View File

@@ -28,11 +28,12 @@ public class ColorFunctions
public static Color applyFunctions( Color color, ColorFunction... functions ) {
float[] hsl = HSLColor.fromRGB( color );
float alpha = color.getAlpha() / 255f;
float[] hsla = { hsl[0], hsl[1], hsl[2], alpha * 100 };
for( ColorFunction function : functions )
function.apply( hsl );
function.apply( hsla );
return HSLColor.toRGB( hsl, alpha );
return HSLColor.toRGB( hsla[0], hsla[1], hsla[2], hsla[3] / 100 );
}
public static float clamp( float value ) {
@@ -46,13 +47,13 @@ public class ColorFunctions
//---- interface ColorFunction --------------------------------------------
public interface ColorFunction {
void apply( float[] hsl );
void apply( float[] hsla );
}
//---- class HSLIncreaseDecrease ------------------------------------------
/**
* Increase or decrease hue, saturation or luminance of a color in the HSL color space
* Increase or decrease hue, saturation, luminance or alpha of a color in the HSL color space
* by an absolute or relative amount.
*/
public static class HSLIncreaseDecrease
@@ -75,18 +76,45 @@ public class ColorFunctions
}
@Override
public void apply( float[] hsl ) {
public void apply( float[] hsla ) {
float amount2 = increase ? amount : -amount;
amount2 = autoInverse && shouldInverse( hsl ) ? -amount2 : amount2;
hsl[hslIndex] = clamp( relative
? (hsl[hslIndex] * ((100 + amount2) / 100))
: (hsl[hslIndex] + amount2) );
if( hslIndex == 0 ) {
// hue is range 0-360
hsla[0] = (hsla[0] + amount2) % 360;
return;
}
amount2 = autoInverse && shouldInverse( hsla ) ? -amount2 : amount2;
hsla[hslIndex] = clamp( relative
? (hsla[hslIndex] * ((100 + amount2) / 100))
: (hsla[hslIndex] + amount2) );
}
protected boolean shouldInverse( float[] hsl ) {
protected boolean shouldInverse( float[] hsla ) {
return increase
? hsl[hslIndex] >= 50
: hsl[hslIndex] < 50;
? hsla[hslIndex] >= 50
: hsla[hslIndex] < 50;
}
}
//---- class HSLIncreaseDecrease ------------------------------------------
/**
* Set the alpha of a color.
*/
public static class Fade
implements ColorFunction
{
public final float amount;
public Fade( float amount ) {
this.amount = amount;
}
@Override
public void apply( float[] hsla ) {
hsla[3] = clamp( amount );
}
}
}

View File

@@ -241,7 +241,7 @@ Slider.trackValueColor=#4A88C7
Slider.trackColor=#646464
Slider.thumbColor=$Slider.trackValueColor
Slider.tickColor=#888
Slider.focusedColor=rgba($Component.focusColor,80%)
Slider.focusedColor=fade($Component.focusColor,80%)
Slider.hoverThumbColor=darken($Slider.thumbColor,10%,derived)
Slider.pressedThumbColor=darken($Slider.thumbColor,15%,derived)
Slider.disabledTrackColor=#4c5052

View File

@@ -682,7 +682,7 @@ TitlePane.foreground=@foreground
TitlePane.inactiveForeground=@disabledText
TitlePane.closeHoverBackground=#e81123
TitlePane.closePressedBackground=rgba($TitlePane.closeHoverBackground,60%)
TitlePane.closePressedBackground=fade($TitlePane.closeHoverBackground,60%)
TitlePane.closeHoverForeground=#fff
TitlePane.closePressedForeground=#fff

View File

@@ -253,7 +253,7 @@ Slider.trackValueColor=#1E82E6
Slider.trackColor=#c4c4c4
Slider.thumbColor=$Slider.trackValueColor
Slider.tickColor=#888
Slider.focusedColor=rgba($Component.focusColor,50%)
Slider.focusedColor=fade($Component.focusColor,50%)
Slider.hoverThumbColor=lighten($Slider.thumbColor,10%,derived)
Slider.pressedThumbColor=lighten($Slider.thumbColor,15%,derived)
Slider.disabledTrackColor=#c0c0c0

View File

@@ -851,7 +851,7 @@ Slider.disabledTrackColor #c0c0c0 javax.swing.plaf.ColorUIResource [UI]
Slider.focus #9e9e9e javax.swing.plaf.ColorUIResource [UI]
Slider.focusInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
Slider.focusWidth 4
Slider.focusedColor #7f97c3f3 javax.swing.plaf.ColorUIResource [UI]
Slider.focusedColor #8097c3f3 javax.swing.plaf.ColorUIResource [UI]
Slider.font [active] $defaultFont [UI]
Slider.foreground #000000 javax.swing.plaf.ColorUIResource [UI]
Slider.highlight #ffffff javax.swing.plaf.ColorUIResource [UI]

View File

@@ -64,6 +64,7 @@ import com.formdev.flatlaf.intellijthemes.FlatAllIJThemes;
import com.formdev.flatlaf.testing.FlatTestLaf;
import com.formdev.flatlaf.ui.FlatLineBorder;
import com.formdev.flatlaf.util.ColorFunctions.ColorFunction;
import com.formdev.flatlaf.util.ColorFunctions.Fade;
import com.formdev.flatlaf.util.ColorFunctions.HSLIncreaseDecrease;
import com.formdev.flatlaf.util.DerivedColor;
import com.formdev.flatlaf.util.StringUtils;
@@ -399,13 +400,18 @@ public class UIDefaultsDump
HSLIncreaseDecrease func = (HSLIncreaseDecrease) function;
String name;
switch( func.hslIndex ) {
case 2: name = func.increase ? "lighten" : "darken"; break;
case 0: name = "spin"; break;
case 1: name = func.increase ? "saturate" : "desaturate"; break;
case 2: name = func.increase ? "lighten" : "darken"; break;
case 3: name = func.increase ? "fadein" : "fadeout"; break;
default: throw new IllegalArgumentException();
}
out.printf( "%s(%.0f%%%s%s)", name, func.amount,
(func.relative ? " relative" : ""),
(func.autoInverse ? " autoInverse" : "") );
} else if( function instanceof Fade ) {
Fade func = (Fade) function;
out.printf( "fade(%.0f%%)", func.amount );
} else
throw new IllegalArgumentException( "unknown color function: " + function );
}

View File

@@ -336,8 +336,9 @@ class FlatCompletionProvider
"lightness", "0-100%",
"alpha", "0-100%" );
String colorParamDesc = "a color (e.g. #f00), a reference (e.g. $Other.key) or a color function";
String[] hslIncreaseDecreaseParams = {
"color", "a color (e.g. #f00), a reference (e.g. $Other.key) or a color function",
"color", colorParamDesc,
"amount", "0-100%",
"options", "(optional) [relative] [autoInverse] [noAutoInverse] [lazy] [derived]"
};
@@ -345,6 +346,17 @@ class FlatCompletionProvider
addFunction( "darken", hslIncreaseDecreaseParams );
addFunction( "saturate", hslIncreaseDecreaseParams );
addFunction( "desaturate", hslIncreaseDecreaseParams );
addFunction( "fadein", hslIncreaseDecreaseParams );
addFunction( "fadeout", hslIncreaseDecreaseParams );
addFunction( "fade",
"color", colorParamDesc,
"amount", "0-100%",
"options", "(optional) [derived]" );
addFunction( "spin",
"color", colorParamDesc,
"angle", "number of degrees to rotate",
"options", "(optional) [derived]" );
}
private void addFunction( String name, String... paramNamesAndDescs ) {

View File

@@ -40,3 +40,12 @@ Prop.colorFunc5=lighten(#fe1289,20%)
Prop.colorFunc6=darken(#fe1289,20%)
Prop.colorFunc7=lighten($Prop.colorFunc4,20%,relative autoInverse)
Prop.colorFunc8=lighten(Prop.colorFunc4,20%,lazy)
Prop.colorFunc9=fadein(#ff000000,30%)
Prop.colorFunc10=fadeout(#ff0000,40%)
Prop.colorFunc11=fade(#ff0000,50%)
Prop.colorFunc12=#f00
Prop.colorFunc13=spin($Prop.colorFunc12,40)
Prop.colorFunc14=spin($Prop.colorFunc12,-40)
Prop.colorFunc15=spin($Prop.colorFunc12,400)
Prop.colorFunc16=spin($Prop.colorFunc12,-400)