From 1024d6fc07cbfd79c22cf9b855541c4dd794d64e Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Sat, 16 Jan 2021 00:39:36 +0100 Subject: [PATCH] UIDefaultsDump: use DerivedColorKeys.properties to compute and dump derived colors and verify them --- .../formdev/flatlaf/FlatLightLaf.properties | 4 +- .../uidefaults/FlatIntelliJLaf_1.8.0_202.txt | 6 ++ .../uidefaults/FlatLightLaf_1.8.0_202.txt | 2 +- .../testing/uidefaults/UIDefaultsDump.java | 91 ++++++++++++++++--- 4 files changed, 87 insertions(+), 16 deletions(-) diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties index f0aec0a4..936c6d22 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties @@ -76,8 +76,8 @@ Button.hoverBorderColor = $Button.focusedBorderColor Button.default.background = $Button.background Button.default.foreground = @foreground Button.default.focusedBackground = $Button.focusedBackground -Button.default.hoverBackground = $Button.hoverBackground -Button.default.pressedBackground = $Button.pressedBackground +Button.default.hoverBackground = darken($Button.default.background,3%,derived) +Button.default.pressedBackground = darken($Button.default.background,10%,derived) Button.default.borderColor = #4F9EE3 Button.default.hoverBorderColor = $Button.hoverBorderColor Button.default.focusedBorderColor = $Button.focusedBorderColor diff --git a/flatlaf-testing/dumps/uidefaults/FlatIntelliJLaf_1.8.0_202.txt b/flatlaf-testing/dumps/uidefaults/FlatIntelliJLaf_1.8.0_202.txt index 1943aed0..673508d6 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatIntelliJLaf_1.8.0_202.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatIntelliJLaf_1.8.0_202.txt @@ -29,9 +29,15 @@ - Button.default.foreground #000000 javax.swing.plaf.ColorUIResource [UI] + Button.default.foreground #ffffff javax.swing.plaf.ColorUIResource [UI] +- Button.default.hoverBackground #f7f7f7 com.formdev.flatlaf.util.DerivedColor [UI] darken(3% autoInverse) ++ Button.default.hoverBackground #4182c5 com.formdev.flatlaf.util.DerivedColor [UI] darken(3% autoInverse) + - Button.default.hoverBorderColor #87afda javax.swing.plaf.ColorUIResource [UI] + Button.default.hoverBorderColor #a9c9f5 javax.swing.plaf.ColorUIResource [UI] +- Button.default.pressedBackground #e6e6e6 com.formdev.flatlaf.util.DerivedColor [UI] darken(10% autoInverse) ++ Button.default.pressedBackground #3571ae com.formdev.flatlaf.util.DerivedColor [UI] darken(10% autoInverse) + - Button.focusedBackground #e3f1fa javax.swing.plaf.ColorUIResource [UI] - CheckBox.icon.focusedBackground #e3f1fa javax.swing.plaf.ColorUIResource [UI] diff --git a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0_202.txt b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0_202.txt index cddf7339..77b5bc74 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0_202.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0_202.txt @@ -785,7 +785,7 @@ RootPane.defaultButtonWindowKeyBindings length=8 [Ljava.lang.Object; [7] release RootPane.honorDialogMinimumSizeOnResize true RootPane.honorFrameMinimumSizeOnResize false -RootPane.inactiveBorderColor #a3a3a3 com.formdev.flatlaf.util.DerivedColor [UI] lighten(20% autoInverse) +RootPane.inactiveBorderColor #bfbfbf / #a3a3a3 com.formdev.flatlaf.util.DerivedColor [UI] lighten(20% autoInverse) RootPaneUI com.formdev.flatlaf.ui.FlatRootPaneUI diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/uidefaults/UIDefaultsDump.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/uidefaults/UIDefaultsDump.java index d29490a5..b4b30986 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/uidefaults/UIDefaultsDump.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/uidefaults/UIDefaultsDump.java @@ -25,6 +25,7 @@ import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.io.InputStream; import java.io.PrintWriter; import java.io.Reader; import java.io.StringReader; @@ -37,6 +38,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; +import java.util.Properties; import java.util.TreeSet; import java.util.function.Predicate; import javax.swing.Icon; @@ -63,6 +65,7 @@ import com.formdev.flatlaf.*; import com.formdev.flatlaf.intellijthemes.FlatAllIJThemes; import com.formdev.flatlaf.testing.FlatTestLaf; import com.formdev.flatlaf.ui.FlatLineBorder; +import com.formdev.flatlaf.ui.FlatUIUtils; import com.formdev.flatlaf.util.ColorFunctions.ColorFunction; import com.formdev.flatlaf.util.ColorFunctions.Fade; import com.formdev.flatlaf.util.ColorFunctions.HSLIncreaseDecrease; @@ -79,6 +82,8 @@ public class UIDefaultsDump { private final LookAndFeel lookAndFeel; private final UIDefaults defaults; + private final Properties derivedColorKeys; + private final boolean isIntelliJTheme; private String lastPrefix; private JComponent dummyComponent; @@ -280,6 +285,9 @@ public class UIDefaultsDump private UIDefaultsDump( LookAndFeel lookAndFeel ) { this.lookAndFeel = lookAndFeel; this.defaults = lookAndFeel.getDefaults(); + + derivedColorKeys = loadDerivedColorKeys(); + isIntelliJTheme = (lookAndFeel instanceof IntelliJTheme.ThemeLaf); } private void dump( PrintWriter out, Predicate keyFilter ) { @@ -316,12 +324,12 @@ public class UIDefaultsDump } out.printf( "%-30s ", strKey ); - dumpValue( out, value ); + dumpValue( out, strKey, value ); out.println(); } ); } - private void dumpValue( PrintWriter out, Object value ) { + private void dumpValue( PrintWriter out, String key, Object value ) { if( value == null || value instanceof String || value instanceof Number || @@ -339,7 +347,7 @@ public class UIDefaultsDump else if( value instanceof List ) dumpList( out, (List) value ); else if( value instanceof Color ) - dumpColor( out, (Color) value ); + dumpColor( out, key, (Color) value ); else if( value instanceof Font ) dumpFont( out, (Font) value ); else if( value instanceof Insets ) @@ -367,7 +375,7 @@ public class UIDefaultsDump out.printf( "length=%d %s", length, dumpClass( array ) ); for( int i = 0; i < length; i++ ) { out.printf( "%n [%d] ", i ); - dumpValue( out, Array.get( array, i ) ); + dumpValue( out, null, Array.get( array, i ) ); } } @@ -375,14 +383,25 @@ public class UIDefaultsDump out.printf( "size=%d %s", list.size(), dumpClass( list ) ); for( int i = 0; i < list.size(); i++ ) { out.printf( "%n [%d] ", i ); - dumpValue( out, list.get( i ) ); + dumpValue( out, null, list.get( i ) ); } } - private void dumpColor( PrintWriter out, Color color ) { - boolean hasAlpha = (color.getAlpha() != 255); - out.printf( hasAlpha ? "#%08x %s" : "#%06x %s", - hasAlpha ? color.getRGB() : (color.getRGB() & 0xffffff), + private void dumpColor( PrintWriter out, String key, Color color ) { + Color resolvedColor = resolveDerivedColor( key, color ); + if( resolvedColor != color && resolvedColor.getRGB() != color.getRGB() ) { + if( !isIntelliJTheme ) { + System.err.println( "Key '" + key + "': derived colors not equal" ); + System.err.println( " Default color: " + dumpColorHex( color ) ); + System.err.println( " Resolved color: " + dumpColorHex( resolvedColor ) ); + } + + out.printf( "%s / ", + dumpColorHex( resolvedColor ) ); + } + + out.printf( "%s %s", + dumpColorHex( color ), dumpClass( color ) ); if( color instanceof DerivedColor ) { @@ -395,6 +414,12 @@ public class UIDefaultsDump } } + private String dumpColorHex( Color color ) { + boolean hasAlpha = (color.getAlpha() != 255); + return String.format( hasAlpha ? "#%08x" : "#%06x", + hasAlpha ? color.getRGB() : (color.getRGB() & 0xffffff) ); + } + private void dumpColorFunction( PrintWriter out, ColorFunction function ) { if( function instanceof HSLIncreaseDecrease ) { HSLIncreaseDecrease func = (HSLIncreaseDecrease) function; @@ -457,7 +482,7 @@ public class UIDefaultsDump if( border instanceof LineBorder ) { LineBorder b = (LineBorder) border; out.print( "line: " ); - dumpValue( out, b.getLineColor() ); + dumpValue( out, null, b.getLineColor() ); out.printf( " %d %b ", b.getThickness(), b.getRoundedCorners() ); } @@ -498,7 +523,7 @@ public class UIDefaultsDump if( border instanceof FlatLineBorder ) { FlatLineBorder lineBorder = (FlatLineBorder) border; out.print( " lineColor=" ); - dumpColor( out, lineBorder.getLineColor() ); + dumpColor( out, null, lineBorder.getLineColor() ); out.printf( " lineThickness=%f", lineBorder.getLineThickness() ); } } @@ -541,7 +566,7 @@ public class UIDefaultsDump private void dumpLazyValue( PrintWriter out, LazyValue value ) { out.print( "[lazy] " ); - dumpValue( out, value.createValue( defaults ) ); + dumpValue( out, null, value.createValue( defaults ) ); } private void dumpActiveValue( PrintWriter out, ActiveValue value ) { @@ -555,7 +580,7 @@ public class UIDefaultsDump if( realValue instanceof UIResource ) out.print( " [UI]" ); } else - dumpValue( out, realValue ); + dumpValue( out, null, realValue ); } private String dumpClass( Object value ) { @@ -565,6 +590,46 @@ public class UIDefaultsDump return classname; } + private Properties loadDerivedColorKeys() { + Properties properties = new Properties(); + try( InputStream in = getClass().getResourceAsStream( "/com/formdev/flatlaf/extras/resources/DerivedColorKeys.properties" ) ) { + properties.load( in ); + } catch( IOException ex ) { + ex.printStackTrace(); + } + return properties; + } + + private Color resolveDerivedColor( String key, Color color ) { + if( !(color instanceof DerivedColor) ) + return color; + + if( key == null ) + throw new NullPointerException( "Key must not null." ); + + Object baseKey = derivedColorKeys.get( key ); + + if( baseKey == null ) + throw new IllegalStateException( "Key '" + key + "' not found in DerivedColorKeys.properties." ); + + // this is for keys that may be defined as derived colors, but do not derive them at runtime + if( "null".equals( baseKey ) ) + return color; + + Color baseColor = defaults.getColor( baseKey ); + if( baseColor == null ) + throw new IllegalStateException( "Missing base color '" + baseKey + "' for key '" + key + "'." ); + + if( baseColor instanceof DerivedColor ) + baseColor = resolveDerivedColor( (String) baseKey, baseColor ); + + Color newColor = FlatUIUtils.deriveColor( color, baseColor ); + + // creating a new color instance to drop Color.frgbvalue from newColor + // and avoid rounding issues/differences + return new Color( newColor.getRGB(), true ); + } + //---- class MyBasicLookAndFeel ------------------------------------------- public static class MyBasicLookAndFeel