From b77b338c7acf83768e3b180720adf7d5083fb9e0 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Thu, 28 Oct 2021 19:03:13 +0200 Subject: [PATCH] Styling: support using variables (defined in properties files) in CSS styles --- .../java/com/formdev/flatlaf/FlatLaf.java | 3 +++ .../com/formdev/flatlaf/UIDefaultsLoader.java | 20 ++++++++++++++++++- .../formdev/flatlaf/ui/TestFlatStyling.java | 14 +++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java index f5311895..88338293 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java @@ -886,6 +886,9 @@ public abstract class FlatLaf public static Object parseDefaultsValue( String key, String value, Class valueType ) throws IllegalArgumentException { + // resolve variables + value = UIDefaultsLoader.resolveValueFromUIManager( value ); + // parse value Object val = UIDefaultsLoader.parseValue( key, value, valueType, null, v -> UIDefaultsLoader.resolveValueFromUIManager( v ), Collections.emptyList() ); diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java index b8133be7..d0ac7aa2 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java @@ -80,6 +80,8 @@ class UIDefaultsLoader private static final String OPTIONAL_PREFIX = "?"; private static final String WILDCARD_PREFIX = "*."; + private static final String FLATLAF_VARIABLES = "FlatLaf.variables"; + private static int parseColorDepth; private static final Cache fontCache = new Cache<>(); @@ -244,10 +246,13 @@ class UIDefaultsLoader }; // parse and add properties to UI defaults + Map variables = new HashMap<>( 50 ); for( Map.Entry e : properties.entrySet() ) { String key = (String) e.getKey(); - if( key.startsWith( VARIABLE_PREFIX ) ) + if( key.startsWith( VARIABLE_PREFIX ) ) { + variables.put( key, (String) e.getValue() ); continue; + } String value = resolveValue( (String) e.getValue(), propertiesGetter ); try { @@ -256,6 +261,9 @@ class UIDefaultsLoader logParseError( key, value, ex, true ); } } + + // remember variables in defaults to allow using them in styles + defaults.put( FLATLAF_VARIABLES, variables ); } catch( IOException ex ) { LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to load properties files.", ex ); } @@ -299,6 +307,16 @@ class UIDefaultsLoader } static String resolveValueFromUIManager( String value ) { + if( value.startsWith( VARIABLE_PREFIX ) ) { + @SuppressWarnings( "unchecked" ) + Map variables = (Map) UIManager.get( FLATLAF_VARIABLES ); + String newValue = (variables != null) ? variables.get( value ) : null; + if( newValue == null ) + throw new IllegalArgumentException( "variable '" + value + "' not found" ); + + return newValue; + } + if( !value.startsWith( PROPERTY_PREFIX ) ) return value; diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java index 9902ed1b..ef273c83 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java @@ -30,6 +30,7 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import com.formdev.flatlaf.icons.*; +import com.formdev.flatlaf.util.ColorFunctions; /** * @author Karl Tauber @@ -157,6 +158,19 @@ public class TestFlatStyling testStyle( "arrowType", "chevron", "$Component.arrowType" ); } + @Test + void parseVariables() { + Color background = UIManager.getColor( "Panel.background" ); + + testColorStyle( background.getRGB(), "@background" ); + testColorStyle( + ColorFunctions.darken( background, 0.2f ).getRGB(), + "darken(@background,20%)" ); + testColorStyle( + ColorFunctions.saturate( ColorFunctions.darken( background, 0.2f ), 0.1f ).getRGB(), + "saturate(darken(@background,20%),10%)" ); + } + private void testColorStyle( int expectedRGB, String style ) { testStyle( "background", new Color( expectedRGB, (expectedRGB & 0xff000000) != 0 ), style ); }