- support references in color functions
- added test for using color functions in styling
This commit is contained in:
Karl Tauber
2021-09-06 22:48:39 +02:00
parent fe15758e59
commit 08ca2aa266
7 changed files with 99 additions and 12 deletions

View File

@@ -32,6 +32,7 @@ import java.beans.PropertyChangeListener;
import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
@@ -796,7 +797,8 @@ public abstract class FlatLaf
throws IllegalArgumentException
{
// parse value
Object val = UIDefaultsLoader.parseValue( key, value, valueType );
Object val = UIDefaultsLoader.parseValue( key, value, valueType, null,
v -> UIDefaultsLoader.resolveValueFromUIManager( v ), Collections.emptyList() );
// create actual value if lazy or active
if( val instanceof LazyValue )

View File

@@ -290,6 +290,25 @@ class UIDefaultsLoader
return resolveValue( newValue, propertiesGetter );
}
static String resolveValueFromUIManager( String value ) {
if( !value.startsWith( PROPERTY_PREFIX ) )
return value;
String key = value.substring( PROPERTY_PREFIX.length() );
Object newValue = UIManager.get( key );
if( newValue == null )
throw new IllegalArgumentException( "property '" + key + "' not found" );
// convert binary color to string
if( newValue instanceof Color ) {
Color color = (Color) newValue;
int alpha = color.getAlpha();
return String.format( (alpha != 255) ? "#%06x%02x" : "#%06x", color.getRGB() & 0xffffff, alpha );
}
throw new IllegalArgumentException( "property value type '" + newValue.getClass().getName() + "' not supported in references" );
}
enum ValueType { UNKNOWN, STRING, BOOLEAN, CHARACTER, INTEGER, FLOAT, BORDER, ICON, INSETS, DIMENSION, COLOR,
SCALEDINTEGER, SCALEDFLOAT, SCALEDINSETS, SCALEDDIMENSION, INSTANCE, CLASS, GRAYFILTER, NULL, LAZY }

View File

@@ -191,6 +191,7 @@ public class FlatStylingSupport
}
private static Object parseValue( String key, String value ) {
// simple reference
if( value.startsWith( "$" ) )
return UIManager.get( value.substring( 1 ) );
@@ -199,6 +200,7 @@ public class FlatStylingSupport
if( key.startsWith( "[" ) )
key = key.substring( key.indexOf( ']' ) + 1 );
// parse string
return FlatLaf.parseDefaultsValue( key, value, null );
}

View File

@@ -19,6 +19,7 @@ package com.formdev.flatlaf.ui;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Insets;
import java.util.HashMap;
import java.util.Map;
@@ -64,6 +65,77 @@ public class TestFlatStyling
FlatStylingSupport.parse( "background: #fff; foreground: #000; someWidth: 20" ) );
}
@Test
void parseColorFunctions() {
testColorStyle( 0x0c2238, "rgb(12,34,56)" );
testColorStyle( 0x4e0c2238, "rgba(12,34,56,78)" );
testColorStyle( 0xb57869, "hsl(12,34%,56%)" );
testColorStyle( 0xc7b57869, "hsla(12,34%,56%,78%)" );
testColorStyle( 0xff6666, "lighten(#f00,20%)" );
testColorStyle( 0x990000, "darken(#f00,20%)" );
testColorStyle( 0x9c3030, "saturate(#844,20%)" );
testColorStyle( 0x745858, "desaturate(#844,20%)" );
testColorStyle( 0x4dff0000, "fadein(#ff000000,30%)" );
testColorStyle( 0x99ff0000, "fadeout(#ff0000,40%)" );
testColorStyle( 0x80ff0000, "fade(#ff0000,50%)" );
testColorStyle( 0xffaa00, "spin(#f00,40)" );
testColorStyle( 0xff00aa, "spin(#f00,-40)" );
testColorStyle( 0x00ffff, "changeHue(#f00,180)" );
testColorStyle( 0xbf4040, "changeSaturation(#f00,50%)" );
testColorStyle( 0xff9999, "changeLightness(#f00,80%)" );
testColorStyle( 0x80ff0000, "changeAlpha(#f00,50%)" );
testColorStyle( 0x1ae600, "mix(#f00,#0f0,10%)" );
testColorStyle( 0x40bf00, "mix(#f00,#0f0,25%)" );
testColorStyle( 0x808000, "mix(#f00,#0f0)" );
testColorStyle( 0xbf4000, "mix(#f00,#0f0,75%)" );
testColorStyle( 0xe61a00, "mix(#f00,#0f0,90%)" );
testColorStyle( 0xff40ff, "tint(#f0f,25%)" );
testColorStyle( 0xff80ff, "tint(#f0f)" );
testColorStyle( 0xffbfff, "tint(#f0f,75%)" );
testColorStyle( 0xbf00bf, "shade(#f0f,25%)" );
testColorStyle( 0x800080, "shade(#f0f)" );
testColorStyle( 0x400040, "shade(#f0f,75%)" );
// nested
testColorStyle( 0xd1c7c7, "saturate(darken(#fff,20%),10%)" );
testColorStyle( 0xcf00cf, "shade(shade(#f0f,10%),10%)" );
testColorStyle( 0xba00ba, "shade(shade(shade(#f0f,10%),10%),10%)" );
}
@Test
void parseReferences() {
assertEquals( Color.white, UIManager.getColor( "TextField.background" ) );
testColorStyle( 0xffffff, "$TextField.background" );
testColorStyle( 0xcccccc, "darken($TextField.background,20%)" );
testColorStyle( 0xd1c7c7, "saturate(darken($TextField.background,20%),10%)" );
testStyle( "hideMnemonics", true, "$Component.hideMnemonics" );
testStyle( "arc", 6, "$Button.arc" );
testStyle( "dropShadowOpacity", 0.15f, "$Popup.dropShadowOpacity" );
testStyle( "margin", new Insets( 2, 14, 2, 14 ) , "$Button.margin" );
testStyle( "iconSize", new Dimension( 64, 64 ), "$DesktopIcon.iconSize" );
testStyle( "arrowType", "chevron", "$Component.arrowType" );
}
private void testColorStyle( int expectedRGB, String style ) {
testStyle( "background", new Color( expectedRGB, (expectedRGB & 0xff000000) != 0 ), style );
}
private void testStyle( String key, Object expected, String style ) {
assertEquals(
expectedMap( key, expected ),
FlatStylingSupport.parse( key + ": " + style ) );
}
private Map<Object, Object> expectedMap( Object... keyValuePairs ) {
Map<Object, Object> map = new HashMap<>();
for( int i = 0; i < keyValuePairs.length; i += 2 )