diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java index 3716bfad..b4f8e008 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java @@ -94,15 +94,20 @@ public class IntelliJTheme if( ui == null ) return; - loadColorPalette( defaults ); + loadNamedColors( defaults ); // convert Json "ui" structure to UI defaults ArrayList defaultsKeysCache = new ArrayList<>(); for( Map.Entry e : ui.entrySet() ) apply( e.getKey(), e.getValue(), defaults, defaultsKeysCache ); + + applyCheckBoxColors( defaults ); } - private void loadColorPalette( UIDefaults defaults ) { + /** + * http://www.jetbrains.org/intellij/sdk/docs/reference_guide/ui_themes/themes_customize.html#defining-named-colors + */ + private void loadNamedColors( UIDefaults defaults ) { if( colors == null ) return; @@ -119,12 +124,21 @@ public class IntelliJTheme } } + /** + * http://www.jetbrains.org/intellij/sdk/docs/reference_guide/ui_themes/themes_customize.html#custom-ui-control-colors + */ @SuppressWarnings( "unchecked" ) private void apply( String key, Object value, UIDefaults defaults, ArrayList defaultsKeysCache ) { if( value instanceof Map ) { for( Map.Entry e : ((Map)value).entrySet() ) apply( key + '.' + e.getKey(), e.getValue(), defaults, defaultsKeysCache ); } else { + // Darcula buttons support gradient for background and border, but FlatLaf does not + if( key.endsWith( ".startBackground" ) || key.endsWith( ".startBorderColor" ) ) + key = key.replace( ".startB", ".b" ); + else if( key.endsWith( ".endBackground" ) || key.endsWith( ".endBorderColor" ) ) + return; // ignore + String valueStr = value.toString(); // map named colors @@ -157,6 +171,68 @@ public class IntelliJTheme } } + /** + * Because Darcula uses SVGs for check boxes and radio buttons the colors for + * this two components are specified in "icons > ColorPalette". + * FlatLaf uses vector icons and expects colors for the two components in UI defaults. + */ + private void applyCheckBoxColors( UIDefaults defaults ) { + if( icons == null ) + return; + + Object palette = icons.get( "ColorPalette" ); + if( !(palette instanceof Map) ) + return; + + boolean checkboxModified = false; + @SuppressWarnings( "unchecked" ) + Map map = (Map) palette; + for( Map.Entry e : map.entrySet() ) { + String key = e.getKey(); + Object value = e.getValue(); + if( !key.startsWith( "Checkbox." ) || !(value instanceof String) ) + continue; + + if( key.endsWith( ".Dark" ) ) + key = key.substring( 0, key.length() - 5 ); + + String newKey = checkboxKeyMapping.get( key ); + if( newKey != null ) { + ColorUIResource color = UIDefaultsLoader.parseColor( (String) value ); + if( color != null ) + defaults.put( newKey, color ); + + checkboxModified = true; + } + } + + // removed colors that Darcula does not provide + if( checkboxModified ) { + defaults.remove( "CheckBox.icon.hoverBorderColor" ); + defaults.remove( "CheckBox.icon.focusedBackground" ); + defaults.remove( "CheckBox.icon.hoverBackground" ); + defaults.remove( "CheckBox.icon.pressedBackground" ); + defaults.remove( "CheckBox.icon.selectedHoverBackground" ); + defaults.remove( "CheckBox.icon.selectedPressedBackground" ); + } + } + + private static Map checkboxKeyMapping = new HashMap<>(); + + static { + checkboxKeyMapping.put( "Checkbox.Background.Default", "CheckBox.icon.background" ); + checkboxKeyMapping.put( "Checkbox.Background.Disabled", "CheckBox.icon.disabledBackground" ); + checkboxKeyMapping.put( "Checkbox.Border.Default", "CheckBox.icon.borderColor" ); + checkboxKeyMapping.put( "Checkbox.Border.Disabled", "CheckBox.icon.disabledBorderColor" ); + checkboxKeyMapping.put( "Checkbox.Focus.Thin.Default", "CheckBox.icon.focusedBorderColor" ); + checkboxKeyMapping.put( "Checkbox.Focus.Wide", "Button.default.focusColor" ); + checkboxKeyMapping.put( "Checkbox.Foreground.Disabled", "CheckBox.icon.disabledCheckmarkColor" ); + checkboxKeyMapping.put( "Checkbox.Background.Selected", "CheckBox.icon.selectedBackground" ); + checkboxKeyMapping.put( "Checkbox.Border.Selected", "CheckBox.icon.selectedBorderColor" ); + checkboxKeyMapping.put( "Checkbox.Foreground.Selected", "CheckBox.icon.checkmarkColor" ); + checkboxKeyMapping.put( "Checkbox.Focus.Thin.Selected", "CheckBox.icon.selectedFocusedBorderColor" ); + } + //---- class LightLaf ----------------------------------------------------- public static class LightLaf