IntelliJ Themes: support customizing through properties files (issue #824)

re-written how .theme.json values are applied:
- old: .theme.json values were applied as last step to a UIDefaults object (after processing all FlatLaf properties files)
- new: .theme.json values are applied to the properties map while loading all FlatLaf properties files
This commit is contained in:
Karl Tauber
2025-03-06 13:14:04 +01:00
parent 143f96360b
commit 9b1ae5c74a
11 changed files with 870 additions and 554 deletions

View File

@@ -24,7 +24,9 @@ FlatLaf Change Log
- Extras: `FlatSVGIcon` color filters now can access painting component to
implement component state based color mappings. (issue #906)
- Linux: Added `libflatlaf-linux-arm64.so` for Linux on ARM64. (issue #899)
- IntelliJ Themes: Updated to latest versions.
- IntelliJ Themes:
- Updated to latest versions and fixed various issues.
- Support customizing through properties files. (issue #824)
#### Fixed bugs

View File

@@ -521,10 +521,10 @@ public abstract class FlatLaf
// load defaults from properties
List<Class<?>> lafClassesForDefaultsLoading = getLafClassesForDefaultsLoading();
if( lafClassesForDefaultsLoading != null )
UIDefaultsLoader.loadDefaultsFromProperties( lafClassesForDefaultsLoading, addons, getAdditionalDefaults(), isDark(), defaults );
else
UIDefaultsLoader.loadDefaultsFromProperties( getClass(), addons, getAdditionalDefaults(), isDark(), defaults );
if( lafClassesForDefaultsLoading == null )
lafClassesForDefaultsLoading = UIDefaultsLoader.getLafClassesForDefaultsLoading( getClass() );
UIDefaultsLoader.loadDefaultsFromProperties( lafClassesForDefaultsLoading, addons,
this::applyAdditionalProperties, getAdditionalDefaults(), isDark(), defaults );
// setup default font after loading defaults from properties
// to allow defining "defaultFont" in properties
@@ -541,9 +541,6 @@ public abstract class FlatLaf
// initialize text antialiasing
putAATextInfo( defaults );
// apply additional defaults (e.g. from IntelliJ themes)
applyAdditionalDefaults( defaults );
// allow addons modifying UI defaults
for( FlatDefaultsAddon addon : addons )
addon.afterDefaultsLoading( this, defaults );
@@ -564,7 +561,8 @@ public abstract class FlatLaf
return defaults;
}
void applyAdditionalDefaults( UIDefaults defaults ) {
// apply additional properties (e.g. from IntelliJ themes)
void applyAdditionalProperties( Properties properties ) {
}
protected List<Class<?>> getLafClassesForDefaultsLoading() {

View File

@@ -16,7 +16,6 @@
package com.formdev.flatlaf;
import java.awt.Color;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -25,20 +24,16 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Map.Entry;
import javax.swing.UIDefaults;
import javax.swing.plaf.ColorUIResource;
import com.formdev.flatlaf.json.Json;
import com.formdev.flatlaf.json.ParseException;
import com.formdev.flatlaf.util.ColorFunctions;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.StringUtils;
import com.formdev.flatlaf.util.SystemInfo;
@@ -63,13 +58,11 @@ public class IntelliJTheme
public final boolean dark;
public final String author;
private final boolean isMaterialUILite;
private Map<String, String> jsonColors;
private Map<String, Object> jsonUI;
private Map<String, Object> jsonIcons;
private Map<String, String> colors;
private Map<String, Object> ui;
private Map<String, Object> icons;
private Map<String, ColorUIResource> namedColors = Collections.emptyMap();
private Map<String, String> namedColors = Collections.emptyMap();
/**
* Loads a IntelliJ .theme.json file from the given input stream,
@@ -84,7 +77,7 @@ public class IntelliJTheme
try {
return FlatLaf.setup( createLaf( in ) );
} catch( Exception ex ) {
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to load IntelliJ theme", ex );
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to load IntelliJ theme", ex );
return false;
}
}
@@ -138,94 +131,90 @@ public class IntelliJTheme
dark = Boolean.parseBoolean( (String) json.get( "dark" ) );
author = (String) json.get( "author" );
isMaterialUILite = author.equals( "Mallowigi" );
colors = (Map<String, String>) json.get( "colors" );
ui = (Map<String, Object>) json.get( "ui" );
icons = (Map<String, Object>) json.get( "icons" );
jsonColors = (Map<String, String>) json.get( "colors" );
jsonUI = (Map<String, Object>) json.get( "ui" );
jsonIcons = (Map<String, Object>) json.get( "icons" );
}
private void applyProperties( UIDefaults defaults ) {
if( ui == null )
private void applyProperties( Properties properties ) {
if( jsonUI == null )
return;
defaults.put( "Component.isIntelliJTheme", true );
put( properties, "Component.isIntelliJTheme", "true" );
// enable button shadows
defaults.put( "Button.paintShadow", true );
defaults.put( "Button.shadowWidth", dark ? 2 : 1 );
put( properties, "Button.paintShadow", "true" );
put( properties, "Button.shadowWidth", dark ? "2" : "1" );
Map<Object, Object> themeSpecificDefaults = removeThemeSpecificDefaults( defaults );
Map<String, String> themeSpecificProps = removeThemeSpecificProps( properties );
Set<String> jsonUIKeys = new HashSet<>();
loadNamedColors( defaults );
// Json node "colors"
loadNamedColors( properties, jsonUIKeys );
// convert Json "ui" structure to UI defaults
ArrayList<Object> defaultsKeysCache = new ArrayList<>();
Set<String> uiKeys = new HashSet<>();
for( Map.Entry<String, Object> e : ui.entrySet() )
apply( e.getKey(), e.getValue(), defaults, defaultsKeysCache, uiKeys );
// convert Json "ui" structure to UI properties
for( Map.Entry<String, Object> e : jsonUI.entrySet() )
apply( e.getKey(), e.getValue(), properties, jsonUIKeys );
applyColorPalette( defaults );
applyCheckBoxColors( defaults );
// set FlatLaf variables
copyIfSetInJson( properties, jsonUIKeys, "@background", "Panel.background", "*.background" );
copyIfSetInJson( properties, jsonUIKeys, "@foreground", "CheckBox.foreground", "*.foreground" );
copyIfSetInJson( properties, jsonUIKeys, "@accentBaseColor",
"ColorPalette.accent", // Material UI Lite, Hiberbee
"ColorPalette.accentColor", // Dracula, One Dark
"ProgressBar.foreground",
"*.selectionBackground" );
copyIfSetInJson( properties, jsonUIKeys, "@accentUnderlineColor", "*.underlineColor", "TabbedPane.underlineColor" );
copyIfSetInJson( properties, jsonUIKeys, "@selectionBackground", "*.selectionBackground" );
copyIfSetInJson( properties, jsonUIKeys, "@selectionForeground", "*.selectionForeground" );
copyIfSetInJson( properties, jsonUIKeys, "@selectionInactiveBackground", "*.selectionInactiveBackground" );
copyIfSetInJson( properties, jsonUIKeys, "@selectionInactiveForeground", "*.selectionInactiveForeground" );
// Json node "icons/ColorPalette"
applyIconsColorPalette( properties );
// apply "CheckBox.icon." colors
applyCheckBoxColors( properties );
// copy values
for( Map.Entry<String, String> e : uiKeyCopying.entrySet() ) {
Object value = defaults.get( e.getValue() );
Object value = properties.get( e.getValue() );
if( value != null )
defaults.put( e.getKey(), value );
put( properties, e.getKey(), value );
}
// IDEA does not paint button background if disabled, but FlatLaf does
Object panelBackground = defaults.get( "Panel.background" );
defaults.put( "Button.disabledBackground", panelBackground );
defaults.put( "ToggleButton.disabledBackground", panelBackground );
put( properties, "Button.disabledBackground", "@disabledBackground" );
put( properties, "ToggleButton.disabledBackground", "@disabledBackground" );
// fix Button borders
copyIfNotSet( defaults, "Button.focusedBorderColor", "Component.focusedBorderColor", uiKeys );
defaults.put( "Button.hoverBorderColor", defaults.get( "Button.focusedBorderColor" ) );
defaults.put( "HelpButton.hoverBorderColor", defaults.get( "Button.focusedBorderColor" ) );
// IDEA uses an SVG icon for the help button, but paints the background with Button.startBackground and Button.endBackground
Object helpButtonBackground = defaults.get( "Button.startBackground" );
Object helpButtonBorderColor = defaults.get( "Button.startBorderColor" );
if( helpButtonBackground == null )
helpButtonBackground = defaults.get( "Button.background" );
if( helpButtonBorderColor == null )
helpButtonBorderColor = defaults.get( "Button.borderColor" );
defaults.put( "HelpButton.background", helpButtonBackground );
defaults.put( "HelpButton.borderColor", helpButtonBorderColor );
defaults.put( "HelpButton.disabledBackground", panelBackground );
defaults.put( "HelpButton.disabledBorderColor", defaults.get( "Button.disabledBorderColor" ) );
defaults.put( "HelpButton.focusedBorderColor", defaults.get( "Button.focusedBorderColor" ) );
defaults.put( "HelpButton.focusedBackground", defaults.get( "Button.focusedBackground" ) );
// fix Button
fixStartEnd( properties, jsonUIKeys, "Button.startBackground", "Button.endBackground", "Button.background" );
fixStartEnd( properties, jsonUIKeys, "Button.startBorderColor", "Button.endBorderColor", "Button.borderColor" );
fixStartEnd( properties, jsonUIKeys, "Button.default.startBackground", "Button.default.endBackground", "Button.default.background" );
fixStartEnd( properties, jsonUIKeys, "Button.default.startBorderColor", "Button.default.endBorderColor", "Button.default.borderColor" );
// IDEA uses TextField.background for editable ComboBox and Spinner
Object textFieldBackground = get( defaults, themeSpecificDefaults, "TextField.background" );
defaults.put( "ComboBox.editableBackground", textFieldBackground );
defaults.put( "Spinner.background", textFieldBackground );
// Spinner arrow button always has same colors as ComboBox arrow button
defaults.put( "Spinner.buttonBackground", defaults.get( "ComboBox.buttonEditableBackground" ) );
defaults.put( "Spinner.buttonArrowColor", defaults.get( "ComboBox.buttonArrowColor" ) );
defaults.put( "Spinner.buttonDisabledArrowColor", defaults.get( "ComboBox.buttonDisabledArrowColor" ) );
Object textFieldBackground = get( properties, themeSpecificProps, "TextField.background" );
put( properties, "ComboBox.editableBackground", textFieldBackground );
put( properties, "Spinner.background", textFieldBackground );
// some themes specify colors for TextField.background, but forget to specify it for other components
// (probably because those components are not used in IntelliJ IDEA)
putAll( defaults, textFieldBackground,
putAll( properties, textFieldBackground,
"EditorPane.background",
"FormattedTextField.background",
"PasswordField.background",
"TextArea.background",
"TextPane.background"
);
putAll( defaults, get( defaults, themeSpecificDefaults, "TextField.selectionBackground" ),
putAll( properties, get( properties, themeSpecificProps, "TextField.selectionBackground" ),
"EditorPane.selectionBackground",
"FormattedTextField.selectionBackground",
"PasswordField.selectionBackground",
"TextArea.selectionBackground",
"TextPane.selectionBackground"
);
putAll( defaults, get( defaults, themeSpecificDefaults, "TextField.selectionForeground" ),
putAll( properties, get( properties, themeSpecificProps, "TextField.selectionForeground" ),
"EditorPane.selectionForeground",
"FormattedTextField.selectionForeground",
"PasswordField.selectionForeground",
@@ -235,7 +224,7 @@ public class IntelliJTheme
// fix disabled and not-editable backgrounds for text components, combobox and spinner
// (IntelliJ IDEA does not use those colors; instead it used background color of parent)
putAll( defaults, panelBackground,
putAll( properties, "@disabledBackground",
"ComboBox.disabledBackground",
"EditorPane.disabledBackground", "EditorPane.inactiveBackground",
"FormattedTextField.disabledBackground", "FormattedTextField.inactiveBackground",
@@ -246,132 +235,148 @@ public class IntelliJTheme
"TextPane.disabledBackground", "TextPane.inactiveBackground"
);
// fix ToggleButton
if( !uiKeys.contains( "ToggleButton.startBackground" ) && !uiKeys.contains( "*.startBackground" ) )
defaults.put( "ToggleButton.startBackground", defaults.get( "Button.startBackground" ) );
if( !uiKeys.contains( "ToggleButton.endBackground" ) && !uiKeys.contains( "*.endBackground" ) )
defaults.put( "ToggleButton.endBackground", defaults.get( "Button.endBackground" ) );
if( !uiKeys.contains( "ToggleButton.foreground" ) && uiKeys.contains( "Button.foreground" ) )
defaults.put( "ToggleButton.foreground", defaults.get( "Button.foreground" ) );
// fix DesktopPane background (use Panel.background and make it 5% darker/lighter)
Color desktopBackgroundBase = defaults.getColor( "Panel.background" );
Color desktopBackground = ColorFunctions.applyFunctions( desktopBackgroundBase,
new ColorFunctions.HSLIncreaseDecrease( 2, dark, 5, false, true ) );
defaults.put( "Desktop.background", new ColorUIResource( desktopBackground ) );
// fix List and Table background colors in Material UI Lite themes
if( isMaterialUILite ) {
defaults.put( "List.background", defaults.get( "Tree.background" ) );
defaults.put( "Table.background", defaults.get( "Tree.background" ) );
}
put( properties, "Desktop.background", dark ? "lighten($Panel.background,5%)" : "darken($Panel.background,5%)" );
// limit tree row height
int rowHeight = defaults.getInt( "Tree.rowHeight" );
String rowHeightStr = (String) properties.get( "Tree.rowHeight" );
int rowHeight = (rowHeightStr != null) ? Integer.parseInt( rowHeightStr ) : 0;
if( rowHeight > 22 )
defaults.put( "Tree.rowHeight", 22 );
put( properties, "Tree.rowHeight", "22" );
// get (and remove) theme specific wildcard replacements, which override all other defaults that end with same suffix
HashMap<String, Object> wildcards = new HashMap<>();
Iterator<Entry<Object, Object>> it = themeSpecificDefaults.entrySet().iterator();
// get (and remove) theme specific wildcard replacements, which override all other properties that end with same suffix
HashMap<String, String> wildcardProps = new HashMap<>();
Iterator<Map.Entry<String, String>> it = themeSpecificProps.entrySet().iterator();
while( it.hasNext() ) {
Entry<Object, Object> e = it.next();
String key = (String) e.getKey();
Map.Entry<String, String> e = it.next();
String key = e.getKey();
if( key.startsWith( "*." ) ) {
wildcards.put( key.substring( "*.".length() ), e.getValue() );
wildcardProps.put( key, e.getValue() );
it.remove();
}
}
// override UI defaults with theme specific wildcard replacements
if( !wildcards.isEmpty() ) {
for( Object key : defaults.keySet().toArray() ) {
int dot;
if( !(key instanceof String) ||
(dot = ((String)key).lastIndexOf( '.' )) < 0 )
continue;
String wildcardKey = ((String)key).substring( dot + 1 );
Object wildcardValue = wildcards.get( wildcardKey );
if( wildcardValue != null )
defaults.put( key, wildcardValue );
}
// override properties with theme specific wildcard replacements
if( !wildcardProps.isEmpty() ) {
for( Map.Entry<String, String> e : wildcardProps.entrySet() )
applyWildcard( properties, e.getKey(), e.getValue() );
}
// apply theme specific UI defaults at the end to allow overwriting
for( Map.Entry<Object, Object> e : themeSpecificDefaults.entrySet() ) {
Object key = e.getKey();
Object value = e.getValue();
// apply theme specific properties at the end to allow overwriting
for( Map.Entry<String, String> e : themeSpecificProps.entrySet() ) {
String key = e.getKey();
String value = e.getValue();
// append styles to existing styles
if( key instanceof String && ((String)key).startsWith( "[style]" ) ) {
Object oldValue = defaults.get( key );
if( key.startsWith( "[style]" ) ) {
String oldValue = (String) properties.get( key );
if( oldValue != null )
value = oldValue + "; " + value;
}
defaults.put( key, value );
put( properties, key, value );
}
// let Java release memory
colors = null;
ui = null;
icons = null;
jsonColors = null;
jsonUI = null;
jsonIcons = null;
}
private Object get( UIDefaults defaults, Map<Object, Object> themeSpecificDefaults, String key ) {
return themeSpecificDefaults.getOrDefault( key, defaults.get( key ) );
private String get( Properties properties, Map<String, String> themeSpecificProps, String key ) {
return themeSpecificProps.getOrDefault( key, (String) properties.get( key ) );
}
private void putAll( UIDefaults defaults, Object value, String... keys ) {
private void put( Properties properties, Object key, Object value ) {
if( value != null )
properties.put( key, value );
else
properties.remove( key );
}
private void putAll( Properties properties, Object value, String... keys ) {
for( String key : keys )
defaults.put( key, value );
put( properties, key, value );
}
private Map<Object, Object> removeThemeSpecificDefaults( UIDefaults defaults ) {
// search for theme specific UI defaults keys
private void copyIfSetInJson( Properties properties, Set<String> jsonUIKeys, String destKey, String... srcKeys ) {
for( String srcKey : srcKeys ) {
if( jsonUIKeys.contains( srcKey ) ) {
Object value = properties.get( srcKey );
if( value != null ) {
put( properties, destKey, value );
break;
}
}
}
}
private void fixStartEnd( Properties properties, Set<String> jsonUIKeys, String startKey, String endKey, String key ) {
if( jsonUIKeys.contains( startKey ) && jsonUIKeys.contains( endKey ) )
put( properties, key, "$" + startKey );
}
private Map<String, String> removeThemeSpecificProps( Properties properties ) {
// search for theme specific properties keys
ArrayList<String> themeSpecificKeys = new ArrayList<>();
for( Object key : defaults.keySet() ) {
if( key instanceof String && ((String)key).startsWith( "{" ) )
for( Object key : properties.keySet() ) {
if( ((String)key).startsWith( "{" ) )
themeSpecificKeys.add( (String) key );
}
// remove theme specific UI defaults and remember only those for current theme
Map<Object, Object> themeSpecificDefaults = new HashMap<>();
// special prefixes (priority from highest to lowest)
String currentThemePrefix = '{' + name.replace( ' ', '_' ) + '}';
String currentThemeAndAuthorPrefix = '{' + name.replace( ' ', '_' ) + "---" + author.replace( ' ', '_' ) + '}';
String currentAuthorPrefix = "{author-" + author.replace( ' ', '_' ) + '}';
String lightOrDarkPrefix = dark ? "{*-dark}" : "{*-light}";
String allThemesPrefix = "{*}";
String[] prefixes = { currentThemePrefix, currentThemeAndAuthorPrefix, currentAuthorPrefix, allThemesPrefix };
String[] prefixes = { currentThemePrefix, currentThemeAndAuthorPrefix, currentAuthorPrefix, lightOrDarkPrefix, allThemesPrefix };
// collect values for special prefixes in its own maps
@SuppressWarnings( "unchecked" )
Map<String, String>[] maps = new Map[prefixes.length];
for( int i = 0; i < maps.length; i++ )
maps[i] = new HashMap<>();
// remove theme specific properties and remember only those for current theme
for( String key : themeSpecificKeys ) {
Object value = defaults.remove( key );
for( String prefix : prefixes ) {
String value = (String) properties.remove( key );
for( int i = 0; i < prefixes.length; i++ ) {
String prefix = prefixes[i];
if( key.startsWith( prefix ) ) {
themeSpecificDefaults.put( key.substring( prefix.length() ), value );
maps[i].put( key.substring( prefix.length() ), value );
break;
}
}
}
return themeSpecificDefaults;
// copy values into single map (from lowest to highest priority)
Map<String, String> themeSpecificProps = new HashMap<>();
for( int i = maps.length - 1; i >= 0; i-- )
themeSpecificProps.putAll( maps[i] );
return themeSpecificProps;
}
/**
* 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 )
private void loadNamedColors( Properties properties, Set<String> jsonUIKeys ) {
if( jsonColors == null )
return;
namedColors = new HashMap<>();
for( Map.Entry<String, String> e : colors.entrySet() ) {
for( Map.Entry<String, String> e : jsonColors.entrySet() ) {
String value = e.getValue();
ColorUIResource color = parseColor( value );
if( color != null ) {
if( canParseColor( value ) ) {
String key = e.getKey();
namedColors.put( key, color );
defaults.put( "ColorPalette." + key, color );
namedColors.put( key, value );
String uiKey = "ColorPalette." + key;
put( properties, uiKey, value );
// this is only necessary for copyIfSetInJson() (used for accent color)
jsonUIKeys.add( uiKey );
}
}
}
@@ -380,7 +385,7 @@ 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<Object> defaultsKeysCache, Set<String> uiKeys ) {
private void apply( String key, Object value, Properties properties, Set<String> jsonUIKeys ) {
if( value instanceof Map ) {
Map<String, Object> map = (Map<String, Object>)value;
if( map.containsKey( "os.default" ) || map.containsKey( "os.windows" ) || map.containsKey( "os.mac" ) || map.containsKey( "os.linux" ) ) {
@@ -388,12 +393,12 @@ public class IntelliJTheme
: SystemInfo.isMacOS ? "os.mac"
: SystemInfo.isLinux ? "os.linux" : null;
if( osKey != null && map.containsKey( osKey ) )
apply( key, map.get( osKey ), defaults, defaultsKeysCache, uiKeys );
apply( key, map.get( osKey ), properties, jsonUIKeys );
else if( map.containsKey( "os.default" ) )
apply( key, map.get( "os.default" ), defaults, defaultsKeysCache, uiKeys );
apply( key, map.get( "os.default" ), properties, jsonUIKeys );
} else {
for( Map.Entry<String, Object> e : map.entrySet() )
apply( key + '.' + e.getKey(), e.getValue(), defaults, defaultsKeysCache, uiKeys );
apply( key + '.' + e.getKey(), e.getValue(), properties, jsonUIKeys );
}
} else {
if( "".equals( value ) )
@@ -418,15 +423,15 @@ public class IntelliJTheme
if( dot > 0 && uiKeyExcludes.contains( key.substring( 0, dot + 1 ) ) )
return;
if( uiKeyDoNotOverride.contains( key ) && uiKeys.contains( key ) )
if( uiKeyDoNotOverride.contains( key ) && jsonUIKeys.contains( key ) )
return;
uiKeys.add( key );
jsonUIKeys.add( key );
String valueStr = value.toString();
// map named colors
Object uiValue = namedColors.get( valueStr );
String uiValue = namedColors.get( valueStr );
// parse value
if( uiValue == null ) {
@@ -445,47 +450,64 @@ public class IntelliJTheme
// parse value
try {
uiValue = UIDefaultsLoader.parseValue( key, valueStr, null );
UIDefaultsLoader.parseValue( key, valueStr, null );
uiValue = valueStr;
} catch( RuntimeException ex ) {
UIDefaultsLoader.logParseError( key, valueStr, ex, false );
UIDefaultsLoader.logParseError( key, valueStr, ex, true );
return; // ignore invalid value
}
}
if( key.startsWith( "*." ) ) {
// wildcard
String tail = key.substring( 1 );
// wildcards
if( applyWildcard( properties, key, uiValue ) )
return;
// because we can not iterate over the UI defaults keys while
// modifying UI defaults in the same loop, we have to copy the keys
if( defaultsKeysCache.size() != defaults.size() ) {
defaultsKeysCache.clear();
Enumeration<Object> e = defaults.keys();
while( e.hasMoreElements() )
defaultsKeysCache.add( e.nextElement() );
}
// replace all values in UI defaults that match the wildcard key
for( Object k : defaultsKeysCache ) {
if( k.equals( "Desktop.background" ) ||
k.equals( "DesktopIcon.background" ) ||
k.equals( "TabbedPane.focusColor" ) )
continue;
if( k instanceof String ) {
// support replacing of mapped keys
// (e.g. set ComboBox.buttonEditableBackground to *.background
// because it is mapped from ComboBox.ArrowButton.background)
String km = uiKeyInverseMapping.getOrDefault( k, (String) k );
if( km.endsWith( tail ) && !((String)k).startsWith( "CheckBox.icon." ) )
defaults.put( k, uiValue );
}
}
} else
defaults.put( key, uiValue );
put( properties, key, uiValue );
}
}
private boolean applyWildcard( Properties properties, String key, String value ) {
if( !key.startsWith( "*." ) )
return false;
String tail = key.substring( 1 );
// because we can not iterate over the properties keys while
// modifying properties in the same loop, we have to copy the keys
String[] keys = properties.keySet().toArray( new String[properties.size()] );
// replace all values in properties that match the wildcard key
for( String k : keys ) {
if( k.startsWith( "*" ) ||
k.startsWith( "@" ) ||
k.startsWith( "HelpButton." ) ||
k.startsWith( "JX" ) ||
k.startsWith( "Jide" ) ||
k.startsWith( "ProgressBar.selection" ) ||
k.startsWith( "TitlePane." ) ||
k.startsWith( "ToggleButton.tab." ) ||
k.equals( "Desktop.background" ) ||
k.equals( "DesktopIcon.background" ) ||
k.equals( "TabbedPane.focusColor" ) ||
k.endsWith( ".hoverBackground" ) ||
k.endsWith( ".pressedBackground" ) )
continue;
// support replacing of mapped keys
// (e.g. set ComboBox.buttonEditableBackground to *.background
// because it is mapped from ComboBox.ArrowButton.background)
String km = uiKeyInverseMapping.getOrDefault( k, k );
if( km.endsWith( tail ) && !k.startsWith( "CheckBox.icon." ) )
put( properties, k, value );
}
// Note: also add wildcards to properties and let UIDefaultsLoader
// process it on BasicLookAndFeel UI defaults
put( properties, key, value );
return true;
}
private String fixColorIfValid( String newColorStr, String colorStr ) {
try {
// check whether it is valid
@@ -497,11 +519,11 @@ public class IntelliJTheme
}
}
private void applyColorPalette( UIDefaults defaults ) {
if( icons == null )
private void applyIconsColorPalette( Properties properties ) {
if( jsonIcons == null )
return;
Object palette = icons.get( "ColorPalette" );
Object palette = jsonIcons.get( "ColorPalette" );
if( !(palette instanceof Map) )
return;
@@ -510,44 +532,48 @@ public class IntelliJTheme
for( Map.Entry<String, Object> e : colorPalette.entrySet() ) {
String key = e.getKey();
Object value = e.getValue();
if( key.startsWith( "Checkbox." ) || !(value instanceof String) )
if( key.startsWith( "Checkbox." ) || key.startsWith( "#" ) || !(value instanceof String) )
continue;
if( dark )
key = StringUtils.removeTrailing( key, ".Dark" );
ColorUIResource color = toColor( (String) value );
String color = toColor( (String) value );
if( color != null )
defaults.put( key, color );
put( properties, key, color );
}
}
private ColorUIResource toColor( String value ) {
private String toColor( String value ) {
if( value.startsWith( "##" ) )
value = fixColorIfValid( value.substring( 1 ), value );
// map named colors
ColorUIResource color = namedColors.get( value );
String color = namedColors.get( value );
// parse color
return (color != null) ? color : parseColor( value );
return (color != null) ? color : (canParseColor( value ) ? value : null);
}
private ColorUIResource parseColor( String value ) {
private boolean canParseColor( String value ) {
try {
return UIDefaultsLoader.parseColor( value );
return UIDefaultsLoader.parseColor( value ) != null;
} catch( IllegalArgumentException ex ) {
return null;
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to parse color: '" + value + '\'', ex );
return false;
}
}
/**
* Because IDEA uses SVGs for check boxes and radio buttons, the colors for
* these two components are specified in "icons > ColorPalette".
* FlatLaf uses vector icons and expects colors for the two components in UI defaults.
* FlatLaf uses vector icons and expects colors for the two components in properties.
*/
private void applyCheckBoxColors( UIDefaults defaults ) {
if( icons == null )
private void applyCheckBoxColors( Properties properties ) {
if( jsonIcons == null )
return;
Object palette = icons.get( "ColorPalette" );
Object palette = jsonIcons.get( "ColorPalette" );
if( !(palette instanceof Map) )
return;
@@ -569,9 +595,9 @@ public class IntelliJTheme
if( !dark && newKey.startsWith( checkBoxIconPrefix ) )
newKey = "CheckBox.icon[filled].".concat( newKey.substring( checkBoxIconPrefix.length() ) );
ColorUIResource color = toColor( (String) value );
String color = toColor( (String) value );
if( color != null ) {
defaults.put( newKey, color );
put( properties, newKey, color );
String key2 = checkboxDuplicateColors.get( key + ".Dark");
if( key2 != null ) {
@@ -592,7 +618,7 @@ public class IntelliJTheme
String newKey2 = checkboxKeyMapping.get( key2 );
if( newKey2 != null )
defaults.put( newKey2, color );
put( properties, newKey2, color );
}
}
@@ -603,13 +629,13 @@ public class IntelliJTheme
// update hover, pressed and focused colors
if( checkboxModified ) {
// for non-filled checkbox/radiobutton used in dark themes
defaults.remove( "CheckBox.icon.focusWidth" );
defaults.put( "CheckBox.icon.hoverBorderColor", defaults.get( "CheckBox.icon.focusedBorderColor" ) );
properties.remove( "CheckBox.icon.focusWidth" );
put( properties, "CheckBox.icon.hoverBorderColor", properties.get( "CheckBox.icon.focusedBorderColor" ) );
// for filled checkbox/radiobutton used in light themes
defaults.remove( "CheckBox.icon[filled].focusWidth" );
defaults.put( "CheckBox.icon[filled].hoverBorderColor", defaults.get( "CheckBox.icon[filled].focusedBorderColor" ) );
defaults.put( "CheckBox.icon[filled].focusedSelectedBackground", defaults.get( "CheckBox.icon[filled].selectedBackground" ) );
properties.remove( "CheckBox.icon[filled].focusWidth" );
put( properties, "CheckBox.icon[filled].hoverBorderColor", properties.get( "CheckBox.icon[filled].focusedBorderColor" ) );
put( properties, "CheckBox.icon[filled].focusedSelectedBackground", properties.get( "CheckBox.icon[filled].selectedBackground" ) );
if( dark ) {
// IDEA Darcula checkBoxFocused.svg, checkBoxSelectedFocused.svg,
@@ -623,21 +649,14 @@ public class IntelliJTheme
"CheckBox.icon[filled].focusedSelectedBorderColor",
};
for( String key : focusedBorderColorKeys ) {
Color color = defaults.getColor( key );
if( color != null ) {
defaults.put( key, new ColorUIResource( new Color(
(color.getRGB() & 0xffffff) | 0xa6000000, true ) ) );
}
Object color = properties.get( key );
if( color != null )
put( properties, key, "fade(" + color + ", 65%)" );
}
}
}
}
private void copyIfNotSet( UIDefaults defaults, String destKey, String srcKey, Set<String> uiKeys ) {
if( !uiKeys.contains( destKey ) )
defaults.put( destKey, defaults.get( srcKey ) );
}
private static final Set<String> uiKeyExcludes;
private static final Set<String> uiKeyDoNotOverride;
/** Rename UI default keys (key --> value). */
@@ -653,26 +672,26 @@ public class IntelliJTheme
uiKeyExcludes = new HashSet<>( Arrays.asList(
"ActionButton.", "ActionToolbar.", "ActionsList.", "AppInspector.", "AssignedMnemonic.", "Autocomplete.",
"AvailableMnemonic.",
"Badge.", "BigSpinner.", "Bookmark.", "BookmarkIcon.", "BookmarkMnemonicAssigned.", "BookmarkMnemonicAvailable.",
"Badge.", "Banner.", "BigSpinner.", "Bookmark.", "BookmarkIcon.", "BookmarkMnemonicAssigned.", "BookmarkMnemonicAvailable.",
"BookmarkMnemonicCurrent.", "BookmarkMnemonicIcon.", "Borders.", "Breakpoint.",
"Canvas.", "Code.", "CodeWithMe.", "CombinedDiff.", "ComboBoxButton.", "CompilationCharts.",
"CompletionPopup.", "ComplexPopup.", "Content.", "ContextHelp.", "CurrentMnemonic.", "Counter.",
"Canvas.", "CellEditor.", "Code.", "CodeWithMe.", "ColumnControlButton.", "CombinedDiff.", "ComboBoxButton.",
"CompilationCharts.", "CompletionPopup.", "ComplexPopup.", "Content.", "ContextHelp.", "CurrentMnemonic.", "Counter.",
"Debugger.", "DebuggerPopup.", "DebuggerTabs.", "DefaultTabs.", "Dialog.", "DialogWrapper.",
"DisclosureButton.", "DragAndDrop.",
"Editor.", "EditorGroupsTabs.", "EditorTabs.",
"FileColor.", "FlameGraph.", "Focus.",
"FileColor.", "FindPopup.", "FlameGraph.", "Focus.",
"Git.", "Github.", "GotItTooltip.", "Group.", "Gutter.", "GutterTooltip.",
"HeaderColor.", "HelpTooltip.", "Hg.",
"IconBadge.", "InformationHint.", "InplaceRefactoringPopup.",
"IconBadge.", "InformationHint.", "InlineBanner.", "InplaceRefactoringPopup.",
"Lesson.", "LineProfiler.", "Link.", "LiveIndicator.",
"MainMenu.", "MainToolbar.", "MemoryIndicator.", "MlModelBinding.", "MnemonicIcon.",
"MainMenu.", "MainToolbar.", "MainWindow.", "MemoryIndicator.", "MlModelBinding.", "MnemonicIcon.",
"NavBar.", "NewClass.", "NewPSD.", "Notification.", "Notifications.", "NotificationsToolwindow.",
"OnePixelDivider.", "OptionButton.", "Outline.",
"ParameterInfo.", "Plugins.", "Profiler.", "ProgressIcon.", "PsiViewer.",
"ReviewList.", "RunWidget.",
"ParameterInfo.", "PresentationAssistant.", "Plugins.", "Profiler.", "ProgressIcon.", "PsiViewer.",
"Resizable.", "Review.", "ReviewList.", "RunToolbar.", "RunWidget.",
"ScreenView.", "SearchEverywhere.", "SearchFieldWithExtension.", "SearchMatch.", "SearchOption.",
"SearchResults.", "SegmentedButton.", "Settings.", "SidePanel.", "Space.", "SpeedSearch.", "StateWidget.",
"StatusBar.",
"StatusBar.", "StripeToolbar.",
"Tag.", "TipOfTheDay.", "ToolbarComboWidget.", "ToolWindow.", "TrialWidget.",
"UIDesigner.", "UnattendedHostStatus.",
"ValidationTooltip.", "VersionControl.",
@@ -689,6 +708,9 @@ public class IntelliJTheme
"TabbedPane.selectedForeground"
) );
// Button
uiKeyMapping.put( "Button.minimumSize", "" ); // ignore (used in Material Theme UI Lite)
// ComboBox
uiKeyMapping.put( "ComboBox.background", "" ); // ignore
uiKeyMapping.put( "ComboBox.buttonBackground", "" ); // ignore
@@ -697,8 +719,6 @@ public class IntelliJTheme
uiKeyMapping.put( "ComboBox.ArrowButton.disabledIconColor", "ComboBox.buttonDisabledArrowColor" );
uiKeyMapping.put( "ComboBox.ArrowButton.iconColor", "ComboBox.buttonArrowColor" );
uiKeyMapping.put( "ComboBox.ArrowButton.nonEditableBackground", "ComboBox.buttonBackground" );
uiKeyCopying.put( "ComboBox.buttonSeparatorColor", "Component.borderColor" );
uiKeyCopying.put( "ComboBox.buttonDisabledSeparatorColor", "Component.disabledBorderColor" );
// Component
uiKeyMapping.put( "Component.inactiveErrorFocusColor", "Component.error.borderColor" );
@@ -706,16 +726,16 @@ public class IntelliJTheme
uiKeyMapping.put( "Component.inactiveWarningFocusColor", "Component.warning.borderColor" );
uiKeyMapping.put( "Component.warningFocusColor", "Component.warning.focusedBorderColor" );
// Label
uiKeyMapping.put( "Label.disabledForegroundColor", "" ); // ignore (used in Material Theme UI Lite)
// Link
uiKeyMapping.put( "Link.activeForeground", "Component.linkColor" );
// Menu
uiKeyMapping.put( "Menu.border", "Menu.margin" );
uiKeyMapping.put( "MenuItem.border", "MenuItem.margin" );
uiKeyCopying.put( "CheckBoxMenuItem.margin", "MenuItem.margin" );
uiKeyCopying.put( "RadioButtonMenuItem.margin", "MenuItem.margin" );
uiKeyMapping.put( "PopupMenu.border", "PopupMenu.borderInsets" );
uiKeyCopying.put( "MenuItem.underlineSelectionColor", "TabbedPane.underlineColor" );
// IDEA uses List.selectionBackground also for menu selection
uiKeyCopying.put( "Menu.selectionBackground", "List.selectionBackground" );
@@ -723,13 +743,11 @@ public class IntelliJTheme
uiKeyCopying.put( "CheckBoxMenuItem.selectionBackground", "List.selectionBackground" );
uiKeyCopying.put( "RadioButtonMenuItem.selectionBackground", "List.selectionBackground" );
// ProgressBar
// ProgressBar: IDEA uses ProgressBar.trackColor and ProgressBar.progressColor
uiKeyMapping.put( "ProgressBar.background", "" ); // ignore
uiKeyMapping.put( "ProgressBar.foreground", "" ); // ignore
uiKeyMapping.put( "ProgressBar.trackColor", "ProgressBar.background" );
uiKeyMapping.put( "ProgressBar.progressColor", "ProgressBar.foreground" );
uiKeyCopying.put( "ProgressBar.selectionForeground", "ProgressBar.background" );
uiKeyCopying.put( "ProgressBar.selectionBackground", "ProgressBar.foreground" );
// ScrollBar
uiKeyMapping.put( "ScrollBar.trackColor", "ScrollBar.track" );
@@ -739,34 +757,30 @@ public class IntelliJTheme
uiKeyMapping.put( "Separator.separatorColor", "Separator.foreground" );
// Slider
uiKeyMapping.put( "Slider.buttonColor", "Slider.thumbColor" );
uiKeyMapping.put( "Slider.buttonBorderColor", "" ); // ignore
uiKeyMapping.put( "Slider.thumb", "" ); // ignore (used in Material Theme UI Lite)
uiKeyMapping.put( "Slider.track", "" ); // ignore (used in Material Theme UI Lite)
uiKeyMapping.put( "Slider.trackDisabled", "" ); // ignore (used in Material Theme UI Lite)
uiKeyMapping.put( "Slider.trackWidth", "" ); // ignore (used in Material Theme UI Lite)
uiKeyCopying.put( "Slider.trackValueColor", "ProgressBar.foreground" );
uiKeyCopying.put( "Slider.thumbColor", "ProgressBar.foreground" );
uiKeyCopying.put( "Slider.trackColor", "ProgressBar.background" );
// Spinner
uiKeyCopying.put( "Spinner.buttonSeparatorColor", "Component.borderColor" );
uiKeyCopying.put( "Spinner.buttonDisabledSeparatorColor", "Component.disabledBorderColor" );
// TabbedPane
uiKeyMapping.put( "DefaultTabs.underlinedTabBackground", "TabbedPane.selectedBackground" );
uiKeyMapping.put( "DefaultTabs.underlinedTabForeground", "TabbedPane.selectedForeground" );
uiKeyMapping.put( "DefaultTabs.inactiveUnderlineColor", "TabbedPane.inactiveUnderlineColor" );
uiKeyMapping.put( "TabbedPane.tabAreaInsets", "" ); // ignore (used in Material Theme UI Lite)
// TableHeader
uiKeyMapping.put( "TableHeader.cellBorder", "" ); // ignore (used in Material Theme UI Lite)
uiKeyMapping.put( "TableHeader.height", "" ); // ignore (used in Material Theme UI Lite)
// TitlePane
uiKeyCopying.put( "TitlePane.inactiveBackground", "TitlePane.background" );
uiKeyMapping.put( "TitlePane.infoForeground", "TitlePane.foreground" );
uiKeyMapping.put( "TitlePane.inactiveInfoForeground", "TitlePane.inactiveForeground" );
for( Map.Entry<String, String> e : uiKeyMapping.entrySet() )
uiKeyInverseMapping.put( e.getValue(), e.getKey() );
uiKeyCopying.put( "ToggleButton.tab.underlineColor", "TabbedPane.underlineColor" );
uiKeyCopying.put( "ToggleButton.tab.disabledUnderlineColor", "TabbedPane.disabledUnderlineColor" );
uiKeyCopying.put( "ToggleButton.tab.selectedBackground", "TabbedPane.selectedBackground" );
uiKeyCopying.put( "ToggleButton.tab.hoverBackground", "TabbedPane.hoverColor" );
uiKeyCopying.put( "ToggleButton.tab.focusBackground", "TabbedPane.focusColor" );
checkboxKeyMapping.put( "Checkbox.Background.Default", "CheckBox.icon.background" );
checkboxKeyMapping.put( "Checkbox.Background.Disabled", "CheckBox.icon.disabledBackground" );
checkboxKeyMapping.put( "Checkbox.Border.Default", "CheckBox.icon.borderColor" );
@@ -819,17 +833,15 @@ public class IntelliJTheme
}
@Override
void applyAdditionalDefaults( UIDefaults defaults ) {
theme.applyProperties( defaults );
void applyAdditionalProperties( Properties properties ) {
theme.applyProperties( properties );
}
@Override
protected ArrayList<Class<?>> getLafClassesForDefaultsLoading() {
ArrayList<Class<?>> lafClasses = new ArrayList<>();
lafClasses.add( FlatLaf.class );
lafClasses.add( theme.dark ? FlatDarkLaf.class : FlatLightLaf.class );
lafClasses.add( theme.dark ? FlatDarculaLaf.class : FlatIntelliJLaf.class );
lafClasses.add( ThemeLaf.class );
ArrayList<Class<?>> lafClasses = UIDefaultsLoader.getLafClassesForDefaultsLoading( getClass() );
lafClasses.add( 1, theme.dark ? FlatDarkLaf.class : FlatLightLaf.class );
lafClasses.add( 2, theme.dark ? FlatDarculaLaf.class : FlatIntelliJLaf.class );
return lafClasses;
}
}

View File

@@ -41,6 +41,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.function.Consumer;
import java.util.function.Function;
import javax.swing.Icon;
import javax.swing.UIDefaults;
@@ -85,15 +86,14 @@ class UIDefaultsLoader
private static final String WILDCARD_PREFIX = "*.";
static final String KEY_VARIABLES = "FlatLaf.internal.variables";
static final String KEY_PROPERTIES = "FlatLaf.internal.properties";
private static int parseColorDepth;
private static Map<String, ColorUIResource> systemColorCache;
private static final SoftCache<String, Object> fontCache = new SoftCache<>();
static void loadDefaultsFromProperties( Class<?> lookAndFeelClass, List<FlatDefaultsAddon> addons,
Properties additionalDefaults, boolean dark, UIDefaults defaults )
{
static ArrayList<Class<?>> getLafClassesForDefaultsLoading( Class<?> lookAndFeelClass ) {
// determine classes in class hierarchy in reverse order
ArrayList<Class<?>> lafClasses = new ArrayList<>();
for( Class<?> lafClass = lookAndFeelClass;
@@ -102,12 +102,11 @@ class UIDefaultsLoader
{
lafClasses.add( 0, lafClass );
}
loadDefaultsFromProperties( lafClasses, addons, additionalDefaults, dark, defaults );
return lafClasses;
}
static void loadDefaultsFromProperties( List<Class<?>> lafClasses, List<FlatDefaultsAddon> addons,
Properties additionalDefaults, boolean dark, UIDefaults defaults )
Consumer<Properties> intellijThemesHook, Properties additionalDefaults, boolean dark, UIDefaults defaults )
{
try {
// temporary cache system colors while loading defaults,
@@ -142,6 +141,10 @@ class UIDefaultsLoader
addonClassLoaders.add( addonClassLoader );
}
// apply IntelliJ themes properties
if( intellijThemesHook != null )
intellijThemesHook.accept( properties );
// load custom properties files (usually provided by applications)
List<Object> customDefaultsSources = FlatLaf.getCustomDefaultsSources();
int size = (customDefaultsSources != null) ? customDefaultsSources.size() : 0;
@@ -287,6 +290,15 @@ class UIDefaultsLoader
// remember variables in defaults to allow using them in styles
defaults.put( KEY_VARIABLES, variables );
// remember properties (for testing)
if( FlatSystemProperties.getBoolean( KEY_PROPERTIES, false ) ) {
Properties properties2 = new Properties();
properties2.putAll( properties );
for( Map.Entry<String, String> e : wildcards.entrySet() )
properties2.put( WILDCARD_PREFIX + e.getKey(), e.getValue() );
defaults.put( KEY_PROPERTIES, properties2 );
}
// clear/disable system color cache
systemColorCache = null;
} catch( IOException ex ) {

View File

@@ -61,7 +61,6 @@ Component.arrowType = triangle
#---- ProgressBar ----
ProgressBar.foreground = darken(@foreground,10%)
ProgressBar.selectionForeground = @background
#---- RadioButton ----

View File

@@ -21,27 +21,41 @@
# - https://www.formdev.com/flatlaf/properties-files/
# - https://www.formdev.com/flatlaf/how-to-customize/
#
# Properties in this file are applied in following order:
# 1. properties without '{...}' and without '[...]' prefix
# 2. properties specified in .theme.json file
# 3. properties starting with '{*}'
# 4. properties starting with '{*-light}' or '{*-dark}'
# 5. properties starting with '{author-<author>}',
# where '<author>' is replaced with "author" value from .theme.json file
# 6. properties starting with '{<name>---<author>}',
# where '<name>' and '<author>' are replaced with "name" and "author" values from .theme.json file
# 7. properties starting with '{<name>}',
# where '<name>' is replaced with "name" value from .theme.json file
# 8. properties with '[...]' prefix
#
#---- system colors ----
# fix (most) system colors because they are usually not set in .json files
desktop = lazy(TextField.background)
activeCaptionText = lazy(TextField.foreground)
inactiveCaptionText = lazy(TextField.foreground)
window = lazy(Panel.background)
windowBorder = lazy(TextField.foreground)
windowText = lazy(TextField.foreground)
menu = lazy(Menu.background)
menuText = lazy(Menu.foreground)
text = lazy(TextField.background)
textText = lazy(TextField.foreground)
textHighlight = lazy(TextField.selectionBackground)
textHighlightText = lazy(TextField.selectionForeground)
textInactiveText = lazy(TextField.inactiveForeground)
control = lazy(Panel.background)
controlText = lazy(TextField.foreground)
info = lazy(ToolTip.background)
infoText = lazy(ToolTip.foreground)
desktop = $TextField.background
activeCaptionText = $TextField.foreground
inactiveCaptionText = $TextField.foreground
window = $Panel.background
windowBorder = $TextField.foreground
windowText = $TextField.foreground
menu = $Menu.background
menuText = $Menu.foreground
text = $TextField.background
textText = $TextField.foreground
textHighlight = $TextField.selectionBackground
textHighlightText = $TextField.selectionForeground
textInactiveText = $TextField.inactiveForeground
control = $Panel.background
controlText = $TextField.foreground
info = $ToolTip.background
infoText = $ToolTip.foreground
#---- variables ----
@@ -49,26 +63,13 @@ infoText = lazy(ToolTip.foreground)
# make sure that accent color (set via FlatLaf.setSystemColorGetter()) is ignored
@accentColor = null
# use same accent color for checkmark, slider, tab underline, etc.
@accentBase2Color = @accentBaseColor
# use fixed color because it is used in borders
@cellFocusColor = #222
#---- Button ----
Button.startBackground = $Button.background
Button.endBackground = $Button.background
Button.startBorderColor = $Button.borderColor
Button.endBorderColor = $Button.borderColor
Button.default.startBackground = $Button.default.background
Button.default.endBackground = $Button.default.background
Button.default.startBorderColor = $Button.default.borderColor
Button.default.endBorderColor = $Button.default.borderColor
Button.hoverBorderColor = null
Button.default.hoverBorderColor = null
#---- CheckBoxMenuItem ----
# colors from intellij/checkmark.svg and darcula/checkmark.svg
@@ -76,19 +77,19 @@ Button.default.hoverBorderColor = null
[dark]CheckBoxMenuItem.icon.checkmarkColor=#fff9
#---- Component ----
Component.accentColor = lazy(ProgressBar.foreground)
#---- HelpButton ----
HelpButton.hoverBorderColor = null
#---- Slider ----
Slider.focusedColor = fade($Component.focusColor,40%,derived)
# this "reverses" definition in FlatLightLaf/FlatDarkLaf.properties
Slider.trackValueColor = $Slider.thumbColor
Slider.thumbColor = @accentSliderColor
#---- Spinner ----
# Spinner arrow button always has same colors as ComboBox arrow button
Spinner.buttonBackground = $ComboBox.buttonEditableBackground
Spinner.buttonArrowColor = $ComboBox.buttonArrowColor
Spinner.buttonDisabledArrowColor = $ComboBox.buttonDisabledArrowColor
#---- TabbedPane ----
@@ -100,10 +101,9 @@ Slider.focusedColor = fade($Component.focusColor,40%,derived)
#---- ToggleButton ----
ToggleButton.startBackground = $ToggleButton.background
ToggleButton.endBackground = $ToggleButton.background
[dark]ToggleButton.selectedBackground = lighten($ToggleButton.background,15%,derived)
[dark]ToggleButton.disabledSelectedBackground = lighten($ToggleButton.background,5%,derived)
{*}ToggleButton.background = $Button.background
{*-dark}ToggleButton.selectedBackground = lighten($ToggleButton.background,15%,derived)
{*-dark}ToggleButton.disabledSelectedBackground = lighten($ToggleButton.background,5%,derived)
#---- theme specific ----
@@ -112,343 +112,434 @@ ToggleButton.endBackground = $ToggleButton.background
@ijMenuCheckBackgroundL20 = lighten(@selectionBackground,20%,derived noAutoInverse)
@ijMenuCheckBackgroundD10 = darken(@selectionBackground,10%,derived noAutoInverse)
@ijTextBackgroundL3 = lighten(Panel.background,3%,lazy)
@ijTextBackgroundL4 = lighten(Panel.background,4%,lazy)
@ijSeparatorLight = shade(@background,15%)
@ijSeparatorDark = tint(@background,25%)
{Arc_Theme}CheckBoxMenuItem.foreground = lazy(MenuItem.foreground)
{Arc_Theme}PopupMenu.foreground = lazy(MenuItem.foreground)
{Arc_Theme}RadioButtonMenuItem.foreground = lazy(MenuItem.foreground)
{Arc_Theme}ProgressBar.selectionBackground = #000
{Arc_Theme}ProgressBar.selectionForeground = #fff
{Arc_Theme}List.selectionInactiveForeground = #fff
{Arc_Theme}Table.selectionInactiveForeground = #fff
{Arc_Theme}Tree.selectionInactiveForeground = #fff
@ijTextBackgroundL3 = lighten($Panel.background,3%)
@ijTextBackgroundL4 = lighten($Panel.background,4%)
{Arc_Theme_-_Orange}CheckBoxMenuItem.foreground = lazy(MenuItem.foreground)
{Arc_Theme_-_Orange}PopupMenu.foreground = lazy(MenuItem.foreground)
{Arc_Theme_-_Orange}RadioButtonMenuItem.foreground = lazy(MenuItem.foreground)
{Arc_Theme_-_Orange}ProgressBar.selectionBackground = #000
{Arc_Theme_-_Orange}ProgressBar.selectionForeground = #fff
{Arc_Theme_-_Orange}List.selectionInactiveForeground = #fff
{Arc_Theme_-_Orange}Table.selectionInactiveForeground = #fff
{Arc_Theme_-_Orange}Tree.selectionInactiveForeground = #fff
{Arc_Theme}@selectionInactiveForeground = @selectionForeground
{Arc_Theme}CheckBoxMenuItem.foreground = $MenuItem.foreground
{Arc_Theme}PopupMenu.foreground = $MenuItem.foreground
{Arc_Theme}RadioButtonMenuItem.foreground = $MenuItem.foreground
{Arc_Theme_Dark}CheckBoxMenuItem.foreground = lazy(MenuItem.foreground)
{Arc_Theme_Dark}PopupMenu.foreground = lazy(MenuItem.foreground)
{Arc_Theme_Dark}RadioButtonMenuItem.foreground = lazy(MenuItem.foreground)
{Arc_Theme_Dark}ProgressBar.selectionBackground = #ddd
{Arc_Theme_Dark}ProgressBar.selectionForeground = #ddd
{Arc_Theme_Dark}ToolBar.separatorColor = lazy(Separator.foreground)
{Arc_Theme_-_Orange}@selectionInactiveForeground = @selectionForeground
{Arc_Theme_-_Orange}CheckBoxMenuItem.foreground = $MenuItem.foreground
{Arc_Theme_-_Orange}PopupMenu.foreground = $MenuItem.foreground
{Arc_Theme_-_Orange}RadioButtonMenuItem.foreground = $MenuItem.foreground
{Arc_Theme_Dark_-_Orange}CheckBoxMenuItem.foreground = lazy(MenuItem.foreground)
{Arc_Theme_Dark_-_Orange}PopupMenu.foreground = lazy(MenuItem.foreground)
{Arc_Theme_Dark_-_Orange}RadioButtonMenuItem.foreground = lazy(MenuItem.foreground)
{Arc_Theme_Dark_-_Orange}ProgressBar.selectionBackground = #ddd
{Arc_Theme_Dark}CheckBoxMenuItem.foreground = $MenuItem.foreground
{Arc_Theme_Dark}PopupMenu.foreground = $MenuItem.foreground
{Arc_Theme_Dark}RadioButtonMenuItem.foreground = $MenuItem.foreground
{Arc_Theme_Dark}ToolBar.background = @background
{Arc_Theme_Dark_-_Orange}CheckBoxMenuItem.foreground = $MenuItem.foreground
{Arc_Theme_Dark_-_Orange}PopupMenu.foreground = $MenuItem.foreground
{Arc_Theme_Dark_-_Orange}ProgressBar.selectionForeground = #fff
{Arc_Theme_Dark_-_Orange}ToolBar.separatorColor = lazy(Separator.foreground)
{Arc_Theme_Dark_-_Orange}RadioButtonMenuItem.foreground = $MenuItem.foreground
{Arc_Theme_Dark_-_Orange}ToolBar.background = @background
{Carbon}Table.selectionBackground = lazy(List.selectionBackground)
{Carbon}Table.selectionInactiveForeground = lazy(List.selectionInactiveForeground)
{Carbon}Separator.foreground = @ijSeparatorDark
{Carbon}ToolBar.separatorColor = $Separator.foreground
{Carbon}Table.selectionBackground = $List.selectionBackground
{Carbon}TextField.background = @ijTextBackgroundL4
{Cobalt_2}Component.accentColor = lazy(Component.focusColor)
{Cobalt_2}CheckBox.icon.background = #002946
{Cobalt_2}CheckBox.icon.checkmarkColor = #002946
{Cobalt_2}@accentBaseColor = $ColorPalette.hue3
{Cobalt_2}CheckBox.icon.background = @background
{Cobalt_2}MenuItem.checkBackground = @ijMenuCheckBackgroundL10
{Cobalt_2}MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
{Cobalt_2}ComboBox.background = @ijTextBackgroundL3
{Cobalt_2}ComboBox.buttonBackground = @ijTextBackgroundL3
{Cobalt_2}Slider.thumbColor = $ProgressBar.foreground
{Cobalt_2}Slider.disabledTrackColor = $Separator.foreground
{Cobalt_2}TextField.background = @ijTextBackgroundL3
{Cobalt_2}Table.background = lazy(List.background)
{Cobalt_2}Tree.background = lazy(List.background)
{Cobalt_2}Table.background = $List.background
{Cobalt_2}Tree.background = $List.background
{Cyan_light}@disabledForeground = tint(@foreground,30%)
{Cyan_light}*.disabledText = @disabledForeground
{Cyan_light}*.disabledForeground = @disabledForeground
{Cyan_light}*.inactiveForeground = @disabledForeground
{Cyan_light}Button.background = @buttonBackground
{Cyan_light}MenuItem.checkBackground = @ijMenuCheckBackgroundL20
{Cyan_light}MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL20
{Dark_Flat_Theme}*.inactiveForeground = #808080
{Dark_Flat_Theme}Component.accentColor = lazy(List.selectionBackground)
{Dark_Flat_Theme}@accentBaseColor = $TabbedPane.underlineColor
{Dark_Flat_Theme}@disabledForeground = #808080
{Dark_Flat_Theme}*.disabledText = @disabledForeground
{Dark_Flat_Theme}*.disabledForeground = @disabledForeground
{Dark_Flat_Theme}*.inactiveForeground = @disabledForeground
{Dark_Flat_Theme}TableHeader.background = #3B3B3B
{Dark_Flat_Theme}TextPane.foreground = lazy(TextField.foreground)
{Dark_Flat_Theme}CheckBoxMenuItem.selectionForeground = lazy(MenuItem.selectionForeground)
{Dark_Flat_Theme}List.selectionForeground = lazy(Tree.selectionForeground)
{Dark_Flat_Theme}RadioButtonMenuItem.selectionForeground = lazy(MenuItem.selectionForeground)
{Dark_Flat_Theme}Separator.foreground = lazy(ToolBar.separatorColor)
{Dark_Flat_Theme}CheckBoxMenuItem.selectionForeground = $MenuItem.selectionForeground
{Dark_Flat_Theme}ComboBox.background = $TextField.background
{Dark_Flat_Theme}ComboBox.buttonBackground = $ComboBox.background
{Dark_Flat_Theme}List.selectionForeground = $Tree.selectionForeground
{Dark_Flat_Theme}ProgressBar.selectionForeground = @foreground
{Dark_Flat_Theme}RadioButtonMenuItem.selectionForeground = $MenuItem.selectionForeground
{Dark_Flat_Theme}Separator.foreground = @ijSeparatorDark
{Dark_Flat_Theme}Slider.trackColor = $ProgressBar.background
{Dark_Flat_Theme}Slider.thumbColor = fade($ProgressBar.foreground,100%)
{Dark_Flat_Theme}TextPane.foreground = $TextField.foreground
{Dark_Flat_Theme}ToggleButton.foreground = $Button.foreground
{Dark_purple}Slider.focusedColor = fade($Component.focusColor,70%,derived)
{Dracula---Zihan_Ma}Component.accentColor = lazy(Component.focusColor)
{Dracula---Zihan_Ma}ComboBox.selectionBackground = lazy(List.selectionBackground)
{Dracula---Zihan_Ma}CheckBox.icon.background = @background
{Dracula---Zihan_Ma}ComboBox.selectionBackground = $List.selectionBackground
{Dracula---Zihan_Ma}ProgressBar.selectionBackground = #fff
{Dracula---Zihan_Ma}ProgressBar.selectionForeground = #fff
{Dracula---Zihan_Ma}Slider.trackColor = $?ColorPalette.selectionBackground
{Dracula---Zihan_Ma}ToggleButton.foreground = $Button.foreground
{Gradianto_Dark_Fuchsia}*.selectionBackground = #8452a7
{Gradianto_Dark_Fuchsia}*.selectionInactiveBackground = #562C6A
{Gradianto_Dark_Fuchsia}MenuItem.checkBackground = @ijMenuCheckBackgroundL10
{Gradianto_Dark_Fuchsia}MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
{Gradianto_Dark_Fuchsia}TextField.background = @ijTextBackgroundL4
{Gradianto_Dark_Fuchsia}Tree.background = lazy(List.background)
{Gradianto_Dark_Fuchsia}Separator.foreground = lazy(ScrollBar.track)
{Gradianto_Dark_Fuchsia}ToolBar.separatorColor = lazy(ScrollBar.track)
{Gradianto_Dark_Fuchsia}ProgressBar.background = lazy(ScrollBar.track)
{Gradianto_Dark_Fuchsia}Slider.trackColor = lazy(ScrollBar.track)
{Gradianto_Dark_Fuchsia}Tree.background = $List.background
{Gradianto_Dark_Fuchsia}Tree.selectionInactiveBackground = $List.selectionInactiveBackground
{Gradianto_Dark_Fuchsia}Separator.foreground = @ijSeparatorDark
{Gradianto_Dark_Fuchsia}ToolBar.separatorColor = $Separator.foreground
{Gradianto_Dark_Fuchsia}ProgressBar.background = $ScrollBar.track
{Gradianto_Dark_Fuchsia}Slider.trackColor = $ScrollBar.track
{Gradianto_Deep_Ocean}Separator.foreground = @ijSeparatorDark
{Gradianto_Deep_Ocean}ToolBar.separatorColor = $Separator.foreground
{Gradianto_Deep_Ocean}TextField.background = @ijTextBackgroundL3
{Gradianto_Deep_Ocean}Tree.background = lazy(List.background)
{Gradianto_Deep_Ocean}Tree.background = $List.background
{Gradianto_Midnight_Blue}ScrollBar.thumb = #533B6B
{Gradianto_Midnight_Blue}Table.selectionForeground = lazy(List.selectionForeground)
{Gradianto_Midnight_Blue}Separator.foreground = @ijSeparatorDark
{Gradianto_Midnight_Blue}ToolBar.separatorColor = $Separator.foreground
{Gradianto_Midnight_Blue}Table.selectionForeground = $List.selectionForeground
{Gradianto_Midnight_Blue}TextField.background = @ijTextBackgroundL4
{Gradianto_Midnight_Blue}Tree.background = lazy(List.background)
{Gradianto_Midnight_Blue}Tree.background = $List.background
{Gradianto_Nature_Green}Table.selectionForeground = lazy(List.selectionForeground)
{Gradianto_Nature_Green}Separator.foreground = @ijSeparatorDark
{Gradianto_Nature_Green}ToolBar.separatorColor = $Separator.foreground
{Gradianto_Nature_Green}Table.selectionForeground = $List.selectionForeground
{Gradianto_Nature_Green}TextField.background = @ijTextBackgroundL4
{Gray}Separator.foreground = lazy(Slider.trackColor)
{Gray}ToolBar.separatorColor = lazy(Slider.trackColor)
{Gray}@disabledForeground = tint(@foreground,40%)
{Gray}*.disabledText = @disabledForeground
{Gray}*.disabledForeground = @disabledForeground
{Gray}*.inactiveForeground = @disabledForeground
{Gray}Button.background = @buttonBackground
{Gray}Separator.foreground = @ijSeparatorLight
{Gray}ToolBar.separatorColor = $Separator.foreground
{Gruvbox_Dark_Hard}Component.accentColor = lazy(TabbedPane.underlineColor)
{Gruvbox_Dark_Hard}ToggleButton.selectedBackground = $ToggleButton.selectedBackground
{Gruvbox_Dark_Hard}ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground
{Gruvbox_Dark_Hard}@accentBaseColor = #4B6EAF
{Gruvbox_Dark_Hard}ComboBox.background = @ijTextBackgroundL3
{Gruvbox_Dark_Hard}ComboBox.buttonBackground = @ijTextBackgroundL3
{Gruvbox_Dark_Hard}ComboBox.buttonBackground = $ComboBox.background
{Gruvbox_Dark_Hard}TextField.background = @ijTextBackgroundL3
{Hiberbee_Dark}*.disabledForeground = #7F7E7D
{Hiberbee_Dark}*.disabledText = #7F7E7D
{Hiberbee_Dark}*.inactiveForeground = #7F7E7D
{Hiberbee_Dark}ProgressBar.background = lazy(Separator.foreground)
{Hiberbee_Dark}Slider.trackColor = lazy(Separator.foreground)
{Hiberbee_Dark}TabbedPane.focusColor = #5A5A5A
{Hiberbee_Dark}TabbedPane.selectedBackground = #434241
{Hiberbee_Dark}TabbedPane.selectedForeground = #70D7FF
{Hiberbee_Dark}ToggleButton.selectedBackground = $ToggleButton.selectedBackground
{Hiberbee_Dark}ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground
{Hiberbee_Dark}Table.selectionInactiveBackground = lazy(List.selectionInactiveBackground)
{Hiberbee_Dark}Tree.selectionBackground = lazy(List.selectionBackground)
{Hiberbee_Dark}Tree.selectionInactiveBackground = lazy(List.selectionInactiveBackground)
{Hiberbee_Dark}@disabledForeground = $ColorPalette.light3
{Hiberbee_Dark}*.disabledText = @disabledForeground
{Hiberbee_Dark}*.disabledForeground = @disabledForeground
{Hiberbee_Dark}*.inactiveForeground = @disabledForeground
{Hiberbee_Dark}List.selectionInactiveBackground = $Table.selectionInactiveBackground
{Hiberbee_Dark}ProgressBar.background = $Separator.foreground
{Hiberbee_Dark}RadioButtonMenuItem.selectionForeground = $MenuItem.selectionForeground
{Hiberbee_Dark}Slider.trackColor = $ColorPalette.light1
{Hiberbee_Dark}Slider.trackColor = $ColorPalette.dark10
{Hiberbee_Dark}Slider.thumbColor = @accentBaseColor
{Hiberbee_Dark}ToggleButton.foreground = $Button.foreground
{Hiberbee_Dark}ToolBar.background = @background
{High_Contrast}Component.accentColor = lazy(Component.focusColor)
{High_Contrast}Button.hoverBorderColor = #1AEBFF
{High_Contrast}HelpButton.hoverBorderColor = #1AEBFF
{High_Contrast}ToggleButton.selectedBackground = #fff
{High_Contrast}ToggleButton.selectedForeground = #000
{High_Contrast}ToggleButton.disabledSelectedBackground = #444
{High_Contrast}ToggleButton.toolbar.selectedBackground = #3333FF
{High_Contrast}@accentBaseColor = $TabbedPane.underlineColor
{High_Contrast}Slider.thumbBorderColor = $Slider.thumbColor
{High_Contrast}Slider.focusedThumbBorderColor = @background
{High_Contrast}Slider.focusedColor = $Component.focusColor
{High_Contrast}Slider.focusWidth = 2
{High_Contrast}ToggleButton.selectedBackground = @selectionBackground
{High_Contrast}ToggleButton.selectedForeground = @selectionForeground
{High_Contrast}ToggleButton.disabledSelectedBackground = shade(@selectionBackground,50%)
{High_Contrast}ToggleButton.toolbar.selectedBackground = @selectionBackground
{High_Contrast}[style]Button.inTextField = \
toolbar.hoverBackground: #444; \
toolbar.pressedBackground: #666; \
toolbar.selectedBackground: #fff
{High_Contrast}[style]ToggleButton.inTextField = ${High_Contrast}[style]Button.inTextField
toolbar.selectedBackground: @selectionBackground
{Light_Flat}*.disabledForeground = #8C8C8C
{Light_Flat}*.inactiveForeground = #8C8C8C
{Light_Flat}@accentBaseColor = $TabbedPane.underlineColor
{Light_Flat}@accentFocusColor = lighten(@accentBaseColor,15%)
{Light_Flat}@disabledForeground = #808080
{Light_Flat}*.disabledText = @disabledForeground
{Light_Flat}*.disabledForeground = @disabledForeground
{Light_Flat}*.inactiveForeground = @disabledForeground
{Light_Flat}CheckBox.icon[filled].background = #fff
{Light_Flat}CheckBox.icon[filled].checkmarkColor = #fff
{Light_Flat}Component.accentColor = lazy(TabbedPane.underlineColor)
{Light_Flat}ComboBox.background = lazy(ComboBox.editableBackground)
{Light_Flat}ComboBox.buttonBackground = lazy(ComboBox.editableBackground)
{Light_Flat}Separator.foreground = lazy(ToolBar.separatorColor)
{Light_Flat}ComboBox.background = $ComboBox.editableBackground
{Light_Flat}ComboBox.buttonBackground = $ComboBox.background
{Light_Flat}ProgressBar.selectionForeground = @foreground
{Light_Flat}Separator.foreground = @ijSeparatorLight
{Light_Flat}TableHeader.background = #E5E5E9
{Light_Flat}TextPane.foreground = lazy(TextField.foreground)
{Light_Flat}CheckBoxMenuItem.selectionForeground = lazy(MenuItem.selectionForeground)
{Light_Flat}RadioButtonMenuItem.selectionForeground = lazy(MenuItem.selectionForeground)
{Light_Flat}TextPane.foreground = $TextField.foreground
{Light_Flat}ToggleButton.foreground = $Button.foreground
{Light_Flat}CheckBoxMenuItem.selectionForeground = $MenuItem.selectionForeground
{Light_Flat}RadioButtonMenuItem.selectionForeground = $MenuItem.selectionForeground
{Monocai}Button.default.foreground = #2D2A2F
{Monocai}@accentUnderlineColor = @accentBaseColor
{Monocai}*.acceleratorForeground = @menuAcceleratorForeground
{Monocai}*.acceleratorSelectionForeground = @menuAcceleratorSelectionForeground
{Monocai}Button.default.foreground = @background
{Monocai}MenuItem.checkBackground = @ijMenuCheckBackgroundL10
{Monocai}MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
@Monocai.acceleratorForeground = lazy(MenuItem.disabledForeground)
@Monocai.acceleratorSelectionForeground = lighten(MenuItem.disabledForeground,10%,lazy)
{Monocai}CheckBoxMenuItem.acceleratorForeground = @Monocai.acceleratorForeground
{Monocai}CheckBoxMenuItem.acceleratorSelectionForeground = @Monocai.acceleratorSelectionForeground
{Monocai}Menu.acceleratorForeground = @Monocai.acceleratorForeground
{Monocai}Menu.acceleratorSelectionForeground = @Monocai.acceleratorSelectionForeground
{Monocai}MenuItem.acceleratorForeground = @Monocai.acceleratorForeground
{Monocai}MenuItem.acceleratorSelectionForeground = @Monocai.acceleratorSelectionForeground
{Monocai}RadioButtonMenuItem.acceleratorForeground = @Monocai.acceleratorForeground
{Monocai}RadioButtonMenuItem.acceleratorSelectionForeground = @Monocai.acceleratorSelectionForeground
{Monocai}TabbedPane.underlineColor = @accentUnderlineColor
{Monocai}TextField.background = @ijTextBackgroundL4
@Monocai.selectionBackground = lazy(TextField.selectionBackground)
@Monocai.selectionBackground = $TextField.selectionBackground
{Monocai}ComboBox.selectionBackground = @Monocai.selectionBackground
{Monocai}List.selectionBackground = @Monocai.selectionBackground
{Monocai}Table.selectionBackground = @Monocai.selectionBackground
{Monocai}Tree.selectionBackground = @Monocai.selectionBackground
@Monocai.selectionInactiveBackground = lazy(MenuItem.selectionBackground)
@Monocai.selectionInactiveBackground = $MenuItem.selectionBackground
{Monocai}List.selectionInactiveBackground = @Monocai.selectionInactiveBackground
{Monocai}Table.selectionInactiveBackground = @Monocai.selectionInactiveBackground
{Monocai}Tree.selectionInactiveBackground = @Monocai.selectionInactiveBackground
{Monokai_Pro---Subtheme}Table.selectionInactiveForeground = lazy(List.selectionInactiveForeground)
{Monokai_Pro---Subtheme}Tree.selectionBackground = lazy(List.selectionBackground)
{Monokai_Pro---Subtheme}Separator.foreground = lazy(Slider.trackColor)
{Monokai_Pro---Subtheme}ToolBar.separatorColor = lazy(Slider.trackColor)
{Monokai_Pro---Subtheme}@disabledForeground = shade(@foreground,40%)
{Monokai_Pro---Subtheme}*.disabledText = @disabledForeground
{Monokai_Pro---Subtheme}*.disabledForeground = @disabledForeground
{Monokai_Pro---Subtheme}*.inactiveForeground = @disabledForeground
{Monokai_Pro---Subtheme}ProgressBar.selectionBackground = #fff
{Monokai_Pro---Subtheme}Table.selectionInactiveForeground = $List.selectionInactiveForeground
{Monokai_Pro---Subtheme}Tree.selectionBackground = $List.selectionBackground
{Monokai_Pro---Subtheme}ToggleButton.foreground = $Button.foreground
{Monokai_Pro---Subtheme}Separator.foreground = @ijSeparatorDark
{Monokai_Pro---Subtheme}ToolBar.separatorColor = $Separator.foreground
{Monokai_Pro---Subtheme}ToolBar.background = @background
{Nord}*.inactiveForeground = #616E88
{Nord}@disabledForeground = #616E88
{Nord}*.disabledText = @disabledForeground
{Nord}*.disabledForeground = @disabledForeground
{Nord}*.inactiveForeground = @disabledForeground
{Nord}MenuItem.checkBackground = @ijMenuCheckBackgroundL10
{Nord}MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
{Nord}List.selectionBackground = lazy(Tree.selectionBackground)
{Nord}List.selectionForeground = lazy(Tree.selectionForeground)
{Nord}Table.selectionBackground = lazy(Tree.selectionBackground)
{Nord}Table.selectionForeground = lazy(Tree.selectionForeground)
{Nord}TextField.selectionBackground = lazy(Tree.selectionBackground)
{Nord}TextField.selectionForeground = lazy(Tree.selectionForeground)
{Nord}Tree.selectionInactiveForeground = lazy(List.selectionInactiveForeground)
{Nord}RadioButtonMenuItem.selectionBackground = $MenuItem.selectionBackground
{Nord}ProgressBar.selectionBackground = @foreground
{Nord}ProgressBar.selectionForeground = @background
{Nord}List.selectionBackground = $Tree.selectionBackground
{Nord}List.selectionForeground = $Tree.selectionForeground
{Nord}Table.selectionBackground = $Tree.selectionBackground
{Nord}Table.selectionForeground = $Tree.selectionForeground
{Nord}TextField.selectionBackground = $Tree.selectionBackground
{Nord}TextField.selectionForeground = $Tree.selectionForeground
{Nord}Tree.selectionInactiveForeground = $List.selectionInactiveForeground
{NotReallyMDTheme}*.selectionInactiveBackground = #21384E
{NotReallyMDTheme}ToolBar.separatorColor = lazy(Separator.foreground)
{NotReallyMDTheme}ToolBar.separatorColor = $Separator.foreground
{One_Dark}List.selectionInactiveForeground = lazy(Tree.selectionInactiveForeground)
{One_Dark}MenuItem.checkBackground = @ijMenuCheckBackgroundL10
{One_Dark}MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
{One_Dark}ProgressBar.background = lazy(Separator.foreground)
{One_Dark}Slider.trackColor = lazy(Separator.foreground)
{One_Dark}Slider.focusedColor = fade(#568af2,40%)
{One_Dark}Table.background = lazy(Tree.background)
{One_Dark}Table.selectionBackground = lazy(Tree.selectionBackground)
{One_Dark}TextField.selectionBackground = lazy(List.selectionBackground)
{One_Dark}Tree.selectionForeground = lazy(List.selectionForeground)
{One_Dark}ProgressBar.background = $Separator.foreground
{One_Dark}ProgressBar.selectionForeground = #fff
{One_Dark}Table.background = $Tree.background
{One_Dark}Table.selectionBackground = $Tree.selectionBackground
{One_Dark}TextField.selectionBackground = $List.selectionBackground
{One_Dark}Tree.selectionForeground = $List.selectionForeground
{Solarized_Dark---4lex4}*.inactiveForeground = #657B83
{Solarized_Dark---4lex4}Component.accentColor = lazy(TabbedPane.underlineColor)
{Solarized_Dark---4lex4}ComboBox.background = lazy(ComboBox.editableBackground)
{Solarized_Dark---4lex4}ComboBox.buttonBackground = lazy(ComboBox.editableBackground)
{Solarized_Dark---4lex4}Slider.focusedColor = fade($Component.focusColor,80%,derived)
{Solarized_Dark---4lex4}ToolBar.separatorColor = lazy(Separator.foreground)
{Solarized_Dark---4lex4}@accentBaseColor = $TabbedPane.underlineColor
{Solarized_Dark---4lex4}*.acceleratorForeground = @menuAcceleratorForeground
{Solarized_Dark---4lex4}ComboBox.background = $ComboBox.editableBackground
{Solarized_Dark---4lex4}ComboBox.buttonBackground = $ComboBox.editableBackground
{Solarized_Dark---4lex4}Slider.disabledTrackColor = $ColorPalette.colorSeparator
{Solarized_Light---4lex4}*.inactiveForeground = #839496
{Solarized_Light---4lex4}Button.default.hoverBackground = darken($Button.default.background,3%,derived)
{Solarized_Light---4lex4}Component.accentColor = lazy(TabbedPane.underlineColor)
{Solarized_Light---4lex4}@accentBaseColor = $TabbedPane.underlineColor
{Solarized_Light---4lex4}Slider.thumbColor = $ProgressBar.foreground
{Solarized_Light---4lex4}Slider.disabledTrackColor = $ColorPalette.colorSeparator
{Spacegray}ComboBox.background = @ijTextBackgroundL4
{Spacegray}ComboBox.buttonBackground = @ijTextBackgroundL4
{Spacegray}ComboBox.buttonBackground = $ComboBox.background
{Spacegray}TextField.background = @ijTextBackgroundL4
{Spacegray}TextField.selectionBackground = lazy(Tree.selectionBackground)
{Spacegray}TextField.selectionForeground = lazy(Tree.selectionForeground)
{vuesion-theme}*.disabledForeground = #8C8C8C
{vuesion-theme}*.disabledText = #8C8C8C
{vuesion-theme}*.inactiveForeground = #8C8C8C
{vuesion-theme}Component.accentColor = lazy(Button.default.endBackground)
{vuesion-theme}@accentBaseColor = $TabbedPane.underlineColor
{vuesion-theme}@disabledForeground = #8C8C8C
{vuesion-theme}*.disabledText = @disabledForeground
{vuesion-theme}*.disabledForeground = @disabledForeground
{vuesion-theme}*.inactiveForeground = @disabledForeground
{vuesion-theme}MenuItem.checkBackground = @ijMenuCheckBackgroundL10
{vuesion-theme}MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
{vuesion-theme}Slider.trackValueColor = #ececee
{vuesion-theme}Slider.trackColor = #303a45
{vuesion-theme}ProgressBar.background = #303a45
{vuesion-theme}ProgressBar.foreground = #ececee
{vuesion-theme}Slider.thumbColor = #ececee
{vuesion-theme}Slider.focusedColor = fade(#ececee,20%)
{vuesion-theme}Slider.focusedColor = fade($Slider.thumbColor,20%)
{vuesion-theme}ComboBox.background = @ijTextBackgroundL4
{vuesion-theme}ComboBox.buttonBackground = @ijTextBackgroundL4
{vuesion-theme}ComboBox.buttonBackground = $ComboBox.background
{vuesion-theme}TextField.background = @ijTextBackgroundL4
{vuesion-theme}TextField.selectionBackground = lighten(#303A45,15%)
{Xcode-Dark}@accentBaseColor = $List.selectionBackground
{Xcode-Dark}TextField.background = @ijTextBackgroundL4
# Material Theme UI Lite
[light]{author-Mallowigi}MenuItem.checkBackground = @ijMenuCheckBackgroundD10
[light]{author-Mallowigi}MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundD10
[dark]{author-Mallowigi}MenuItem.checkBackground = @ijMenuCheckBackgroundL20
[dark]{author-Mallowigi}MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL20
{author-Mallowigi}[light]controlHighlight = lighten($controlShadow,8%)
{author-Mallowigi}[light]controlLtHighlight = lighten($controlShadow,15%)
{author-Mallowigi}[light]controlDkShadow = darken($controlShadow,15%)
{author-Mallowigi}[dark]controlHighlight = darken($controlShadow,10%)
{author-Mallowigi}[dark]controlLtHighlight = darken($controlShadow,15%)
{author-Mallowigi}[dark]controlDkShadow = lighten($controlShadow,10%)
{author-Mallowigi}Tree.selectionInactiveBackground = lazy(List.selectionInactiveBackground)
{author-Mallowigi}Button.hoverBorderColor = $Button.focusedBorderColor
{author-Mallowigi}HelpButton.hoverBorderColor = $Button.focusedBorderColor
{Arc_Dark}ComboBox.selectionBackground = lazy(List.selectionBackground)
{Arc_Dark}Table.selectionBackground = lazy(List.selectionBackground)
{author-Mallowigi}[light]ToggleButton.selectedForeground = #000
{author-Mallowigi}[dark]ToggleButton.selectedForeground = #fff
{Atom_One_Dark}Separator.foreground = lazy(Slider.trackColor)
{Atom_One_Dark}ToolBar.separatorColor = lazy(Slider.trackColor)
{author-Mallowigi}[light]MenuItem.checkBackground = @ijMenuCheckBackgroundD10
{author-Mallowigi}[light]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundD10
{author-Mallowigi}[dark]MenuItem.checkBackground = @ijMenuCheckBackgroundL20
{author-Mallowigi}[dark]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL20
{Atom_One_Light}List.selectionBackground = lazy(Table.selectionBackground)
{Atom_One_Light}Tree.selectionBackground = lazy(Table.selectionBackground)
{Atom_One_Light}TabbedPane.contentAreaColor = lazy(Separator.foreground)
{author-Mallowigi}[light]Separator.foreground = @ijSeparatorLight
{author-Mallowigi}[dark]Separator.foreground = @ijSeparatorDark
{author-Mallowigi}ProgressBar.selectionBackground = @foreground
{author-Mallowigi}TabbedPane.selectedBackground = mix(@background,$ColorPalette.table,60%)
{author-Mallowigi}ToolBar.separatorColor = $Separator.foreground
{author-Mallowigi}Button.foreground = @foreground
{author-Mallowigi}Tree.foreground = @foreground
{Arc_Dark}ComboBox.selectionBackground = $List.selectionBackground
{Arc_Dark}ProgressBar.selectionBackground = #fff
{Arc_Dark}ProgressBar.selectionForeground = #fff
{Arc_Dark}Table.selectionBackground = $List.selectionBackground
{Arc_Dark}Tree.selectionInactiveBackground = $List.selectionInactiveBackground
{Atom_One_Dark}ProgressBar.selectionBackground = #fff
{Atom_One_Dark}ProgressBar.selectionForeground = #fff
{Atom_One_Dark}List.selectionBackground = $Table.selectionBackground
{Atom_One_Dark}Tree.selectionBackground = $Table.selectionBackground
{Atom_One_Dark}List.selectionInactiveBackground = $Tree.selectionInactiveBackground
{Atom_One_Dark}Table.selectionInactiveBackground = $Tree.selectionInactiveBackground
{Atom_One_Light}@disabledForeground = shade($ColorPalette.dis,20%)
{Atom_One_Light}*.disabledText = @disabledForeground
{Atom_One_Light}*.disabledForeground = @disabledForeground
{Atom_One_Light}*.inactiveForeground = @disabledForeground
{Atom_One_Light}TabbedPane.contentAreaColor = $Separator.foreground
{Dracula---Mallowigi}*.selectionBackground = #44475A
{Dracula---Mallowigi}List.selectionInactiveForeground = lazy(Tree.selectionInactiveForeground)
{Dracula---Mallowigi}ProgressBar.selectionBackground = #fff
{Dracula---Mallowigi}ProgressBar.selectionForeground = #fff
{Dracula---Mallowigi}RadioButtonMenuItem.selectionForeground = lazy(CheckBoxMenuItem.selectionForeground)
{Dracula---Mallowigi}Table.selectionForeground = lazy(List.selectionForeground)
{Dracula---Mallowigi}Separator.foreground = lazy(Slider.trackColor)
{Dracula---Mallowigi}ToolBar.separatorColor = lazy(Slider.trackColor)
{Dracula---Mallowigi}List.selectionBackground = $Table.selectionBackground
{Dracula---Mallowigi}Tree.selectionBackground = $Table.selectionBackground
{Dracula---Mallowigi}List.selectionInactiveBackground = $Tree.selectionInactiveBackground
{Dracula---Mallowigi}Table.selectionInactiveBackground = $Tree.selectionInactiveBackground
{GitHub}ProgressBar.selectionBackground = #222
{GitHub}ProgressBar.selectionForeground = #222
{GitHub}TextField.background = @ijTextBackgroundL3
{GitHub}List.selectionBackground = lazy(Table.selectionBackground)
{GitHub}Tree.selectionBackground = lazy(Table.selectionBackground)
{GitHub}List.selectionBackground = $Table.selectionBackground
{GitHub}Tree.selectionBackground = $Table.selectionBackground
{GitHub}List.selectionInactiveBackground = $Tree.selectionInactiveBackground
{GitHub}Table.selectionInactiveBackground = $Tree.selectionInactiveBackground
{GitHub_Dark}ComboBox.selectionBackground = lazy(Tree.selectionBackground)
{GitHub_Dark}Table.selectionBackground = lazy(Tree.selectionBackground)
{GitHub_Dark}Separator.foreground = lazy(Slider.trackColor)
{GitHub_Dark}ToolBar.separatorColor = lazy(Slider.trackColor)
{GitHub_Dark}ComboBox.selectionBackground = $Tree.selectionBackground
{GitHub_Dark}ProgressBar.selectionForeground = #fff
{GitHub_Dark}Slider.trackColor = lighten(#2b3036,5%)
{GitHub_Dark}Table.selectionBackground = $Tree.selectionBackground
{GitHub_Dark}Tree.selectionInactiveBackground = $Table.selectionInactiveBackground
{Light_Owl}CheckBoxMenuItem.selectionForeground = lazy(CheckBoxMenuItem.foreground)
{Light_Owl}ComboBox.selectionForeground = lazy(ComboBox.foreground)
{Light_Owl}List.selectionInactiveForeground = lazy(List.foreground)
{Light_Owl}Menu.selectionForeground = lazy(Menu.foreground)
{Light_Owl}MenuBar.selectionForeground = lazy(MenuBar.foreground)
{Light_Owl}MenuItem.selectionForeground = lazy(MenuItem.foreground)
{Light_Owl}ProgressBar.selectionBackground = #111
{Light_Owl}ProgressBar.selectionForeground = #fff
{Light_Owl}Spinner.selectionForeground = lazy(Spinner.foreground)
{Light_Owl}Table.selectionForeground = lazy(Table.foreground)
{Light_Owl}TextField.selectionForeground = lazy(TextField.foreground)
{Light_Owl}@disabledForeground = shade($ColorPalette.dis,10%)
{Light_Owl}*.disabledText = @disabledForeground
{Light_Owl}*.disabledForeground = @disabledForeground
{Light_Owl}*.inactiveForeground = @disabledForeground
{Light_Owl}CheckBoxMenuItem.selectionForeground = $CheckBoxMenuItem.foreground
{Light_Owl}ComboBox.selectionForeground = $ComboBox.foreground
{Light_Owl}List.selectionInactiveForeground = $Table.selectionInactiveForeground
{Light_Owl}Menu.selectionForeground = $Menu.foreground
{Light_Owl}MenuBar.selectionForeground = $MenuBar.foreground
{Light_Owl}MenuItem.selectionForeground = $MenuItem.foreground
{Light_Owl}Table.selectionForeground = $List.selectionForeground
{Light_Owl}TextField.selectionForeground = $TextField.foreground
{Light_Owl}TextField.background = @ijTextBackgroundL3
{Light_Owl}List.selectionBackground = lazy(Table.selectionBackground)
{Light_Owl}Tree.selectionBackground = lazy(Table.selectionBackground)
{Light_Owl}List.selectionBackground = $Table.selectionBackground
{Light_Owl}Tree.selectionBackground = $Table.selectionBackground
{Light_Owl}List.selectionInactiveBackground = $Tree.selectionInactiveBackground
{Light_Owl}Table.selectionInactiveBackground = $Tree.selectionInactiveBackground
{Material_Darker}*.selectionBackground = lighten(#2D2D2D,15%)
{Material_Darker}Separator.foreground = lazy(Slider.trackColor)
{Material_Darker}ToolBar.separatorColor = lazy(Slider.trackColor)
{Material_Darker}@disabledForeground = tint($ColorPalette.dis,30%)
{Material_Darker}*.disabledText = @disabledForeground
{Material_Darker}*.disabledForeground = @disabledForeground
{Material_Darker}*.inactiveForeground = @disabledForeground
{Material_Darker}*.selectionBackground = lighten($ColorPalette.tree,15%)
{Material_Darker}ProgressBar.selectionForeground = #fff
{Material_Darker}Tree.selectionInactiveBackground = $List.selectionInactiveBackground
{Material_Deep_Ocean}*.selectionBackground = lighten(#222533,15%)
{Material_Deep_Ocean}Separator.foreground = lazy(Slider.trackColor)
{Material_Deep_Ocean}ToolBar.separatorColor = lazy(Slider.trackColor)
{Material_Deep_Ocean}@disabledForeground = tint($ColorPalette.dis,10%)
{Material_Deep_Ocean}*.disabledText = @disabledForeground
{Material_Deep_Ocean}*.disabledForeground = @disabledForeground
{Material_Deep_Ocean}*.inactiveForeground = @disabledForeground
{Material_Deep_Ocean}*.selectionBackground = lighten($ColorPalette.tree,15%)
{Material_Deep_Ocean}ProgressBar.selectionBackground = #fff
{Material_Deep_Ocean}Slider.trackColor = lighten(#1A1C25,5%)
{Material_Deep_Ocean}Tree.selectionInactiveBackground = $List.selectionInactiveBackground
{Material_Lighter}List.selectionInactiveForeground = lazy(Tree.selectionInactiveForeground)
{Material_Lighter}@disabledForeground = shade($ColorPalette.dis,30%)
{Material_Lighter}*.disabledText = @disabledForeground
{Material_Lighter}*.disabledForeground = @disabledForeground
{Material_Lighter}*.inactiveForeground = @disabledForeground
{Material_Lighter}ComboBox.selectionBackground = $List.selectionBackground
{Material_Lighter}List.selectionForeground = $Table.selectionForeground
{Material_Lighter}List.selectionInactiveForeground = $Table.selectionInactiveForeground
{Material_Lighter}ProgressBar.selectionBackground = #222
{Material_Lighter}ProgressBar.selectionForeground = #fff
{Material_Lighter}ComboBox.selectionBackground = lazy(List.selectionBackground)
{Material_Lighter}Table.selectionBackground = lazy(List.selectionBackground)
{Material_Lighter}List.selectionForeground = lazy(Table.selectionForeground)
{Material_Lighter}RadioButtonMenuItem.selectionForeground = lazy(Table.selectionForeground)
{Material_Lighter}Tree.selectionForeground = lazy(Table.selectionForeground)
{Material_Lighter}RadioButtonMenuItem.selectionForeground = $Table.selectionForeground
{Material_Lighter}Table.selectionBackground = $List.selectionBackground
{Material_Lighter}Tree.selectionForeground = $Table.selectionForeground
{Material_Lighter}Tree.selectionInactiveBackground = $List.selectionInactiveBackground
{Material_Oceanic}@disabledForeground = tint($ColorPalette.dis,30%)
{Material_Oceanic}*.disabledText = @disabledForeground
{Material_Oceanic}*.disabledForeground = @disabledForeground
{Material_Oceanic}*.inactiveForeground = @disabledForeground
{Material_Oceanic}ProgressBar.selectionBackground = #ddd
{Material_Oceanic}ProgressBar.selectionForeground = #ddd
{Material_Oceanic}Separator.foreground = lazy(Slider.trackColor)
{Material_Oceanic}ToolBar.separatorColor = lazy(Slider.trackColor)
{Material_Oceanic}List.selectionBackground = $Table.selectionBackground
{Material_Oceanic}Tree.selectionBackground = $Table.selectionBackground
{Material_Oceanic}List.selectionInactiveBackground = $Tree.selectionInactiveBackground
{Material_Oceanic}Table.selectionInactiveBackground = $Tree.selectionInactiveBackground
{Material_Palenight}@disabledForeground = tint($ColorPalette.dis,20%)
{Material_Palenight}*.disabledText = @disabledForeground
{Material_Palenight}*.disabledForeground = @disabledForeground
{Material_Palenight}*.inactiveForeground = @disabledForeground
{Material_Palenight}ProgressBar.selectionBackground = #ddd
{Material_Palenight}ProgressBar.selectionForeground = #ddd
{Material_Palenight}List.selectionBackground = lazy(Table.selectionBackground)
{Material_Palenight}Tree.selectionBackground = lazy(Table.selectionBackground)
{Material_Palenight}Separator.foreground = lazy(Slider.trackColor)
{Material_Palenight}ToolBar.separatorColor = lazy(Slider.trackColor)
{Material_Palenight}List.selectionBackground = $Table.selectionBackground
{Material_Palenight}Tree.selectionBackground = $Table.selectionBackground
{Material_Palenight}List.selectionInactiveBackground = $Tree.selectionInactiveBackground
{Material_Palenight}Table.selectionInactiveBackground = $Tree.selectionInactiveBackground
{Monokai_Pro---Mallowigi}List.selectionForeground = lazy(Table.selectionForeground)
{Monokai_Pro---Mallowigi}RadioButtonMenuItem.selectionForeground = lazy(Table.selectionForeground)
{Monokai_Pro---Mallowigi}Table.selectionInactiveForeground = lazy(List.selectionInactiveForeground)
{Monokai_Pro---Mallowigi}Tree.selectionForeground = lazy(Table.selectionForeground)
{Monokai_Pro---Mallowigi}Tree.selectionInactiveForeground = lazy(List.selectionInactiveForeground)
{Monokai_Pro---Mallowigi}Separator.foreground = lazy(Slider.trackColor)
{Monokai_Pro---Mallowigi}ToolBar.separatorColor = lazy(Slider.trackColor)
{Monokai_Pro---Mallowigi}@disabledForeground = tint($ColorPalette.dis,20%)
{Monokai_Pro---Mallowigi}*.disabledText = @disabledForeground
{Monokai_Pro---Mallowigi}*.disabledForeground = @disabledForeground
{Monokai_Pro---Mallowigi}*.inactiveForeground = @disabledForeground
{Monokai_Pro---Mallowigi}RadioButtonMenuItem.selectionForeground = $MenuItem.selectionForeground
{Monokai_Pro---Mallowigi}List.selectionForeground = $Table.selectionForeground
{Monokai_Pro---Mallowigi}Tree.selectionForeground = $Table.selectionForeground
{Monokai_Pro---Mallowigi}List.selectionInactiveForeground = $Table.selectionInactiveForeground
{Monokai_Pro---Mallowigi}List.selectionBackground = $Table.selectionBackground
{Monokai_Pro---Mallowigi}Tree.selectionBackground = $Table.selectionBackground
{Monokai_Pro---Mallowigi}List.selectionInactiveBackground = $Tree.selectionInactiveBackground
{Monokai_Pro---Mallowigi}Table.selectionInactiveBackground = $Tree.selectionInactiveBackground
{Moonlight}ComboBox.selectionBackground = lazy(List.selectionBackground)
{Moonlight}Table.selectionBackground = lazy(List.selectionBackground)
{Moonlight}Separator.foreground = lazy(Slider.trackColor)
{Moonlight}ToolBar.separatorColor = lazy(Slider.trackColor)
{Night_Owl}ProgressBar.selectionBackground = #ddd
{Night_Owl}ProgressBar.selectionForeground = #ddd
{Moonlight}ComboBox.selectionBackground = $List.selectionBackground
{Moonlight}ProgressBar.selectionForeground = #000
{Moonlight}Table.selectionBackground = $List.selectionBackground
{Moonlight}Tree.selectionInactiveBackground = $List.selectionInactiveBackground
{Solarized_Dark---Mallowigi}@disabledForeground = tint($ColorPalette.dis,20%)
{Solarized_Dark---Mallowigi}*.disabledForeground = @disabledForeground
{Solarized_Dark---Mallowigi}*.inactiveForeground = @disabledForeground
{Solarized_Dark---Mallowigi}*.disabledText = @disabledForeground
{Solarized_Dark---Mallowigi}ProgressBar.selectionBackground = #ccc
{Solarized_Dark---Mallowigi}ProgressBar.selectionForeground = #ccc
{Solarized_Dark---Mallowigi}Separator.foreground = lazy(Slider.trackColor)
{Solarized_Dark---Mallowigi}ToolBar.separatorColor = lazy(Slider.trackColor)
{Solarized_Dark---Mallowigi}Slider.trackColor = lighten(@background,10%)
{Solarized_Dark---Mallowigi}Table.selectionBackground = $List.selectionBackground
{Solarized_Dark---Mallowigi}Tree.selectionInactiveBackground = $List.selectionInactiveBackground
{Solarized_Light---Mallowigi}@disabledForeground = tint(@foreground,30%)
{Solarized_Light---Mallowigi}*.disabledForeground = @disabledForeground
{Solarized_Light---Mallowigi}*.inactiveForeground = @disabledForeground
{Solarized_Light---Mallowigi}*.disabledText = @disabledForeground
{Solarized_Light---Mallowigi}ProgressBar.selectionBackground = #222
{Solarized_Light---Mallowigi}ProgressBar.selectionForeground = #fff
{Solarized_Light---Mallowigi}ComboBox.selectionBackground = lazy(List.selectionBackground)
{Solarized_Light---Mallowigi}Table.selectionBackground = lazy(List.selectionBackground)
{Solarized_Light---Mallowigi}Separator.foreground = lazy(Slider.trackColor)
{Solarized_Light---Mallowigi}ToolBar.separatorColor = lazy(Slider.trackColor)
{Solarized_Light---Mallowigi}ComboBox.selectionBackground = $List.selectionBackground
{Solarized_Light---Mallowigi}Slider.disabledTrackColor = lighten($Slider.trackColor,5%)
{Solarized_Light---Mallowigi}Table.selectionBackground = $List.selectionBackground
{Solarized_Light---Mallowigi}Tree.selectionInactiveBackground = $List.selectionInactiveBackground
{Solarized_Light---Mallowigi}Button.toolbar.selectedBackground = darken($@background,15%)
{Solarized_Light---Mallowigi}ToggleButton.toolbar.selectedBackground = $Button.toolbar.selectedBackground

View File

@@ -52,6 +52,8 @@ public class DemoPrefs
}
public static void setupLaf( String[] args ) {
// com.formdev.flatlaf.demo.intellijthemes.IJThemesDump.install();
// set look and feel
try {
if( args.length > 0 )

View File

@@ -0,0 +1,118 @@
/*
* Copyright 2025 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.demo.intellijthemes;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicReference;
import javax.swing.LookAndFeel;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.IntelliJTheme;
import com.formdev.flatlaf.util.LoggingFacade;
/**
* @author Karl Tauber
*/
public class IJThemesDump
{
// same as UIDefaultsLoader.KEY_PROPERTIES
private static final String KEY_PROPERTIES = "FlatLaf.internal.properties";
public static void enablePropertiesRecording() {
System.setProperty( KEY_PROPERTIES, "true" );
}
public static void install() {
enablePropertiesRecording();
UIManager.addPropertyChangeListener( e -> {
if( "lookAndFeel".equals( e.getPropertyName() ) ) {
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
if( lookAndFeel instanceof IntelliJTheme.ThemeLaf ) {
IntelliJTheme theme = (lookAndFeel.getClass() == IntelliJTheme.ThemeLaf.class)
? ((IntelliJTheme.ThemeLaf)lookAndFeel).getTheme()
: null;
String name = (theme != null) ? theme.name : lookAndFeel.getClass().getSimpleName();
File dir = new File( "dumps/properties" );
dumpProperties( dir, name, UIManager.getLookAndFeelDefaults() );
}
}
} );
}
public static void dumpProperties( File dir, String name, UIDefaults defaults ) {
String content = dumpPropertiesToString( defaults );
if( content == null )
return;
// write to file
File file = new File( dir, name + ".properties" );
file.getParentFile().mkdirs();
try( Writer fileWriter = new OutputStreamWriter(
new FileOutputStream( file ), StandardCharsets.UTF_8 ) )
{
fileWriter.write( content );
} catch( IOException ex ) {
LoggingFacade.INSTANCE.logSevere( null, ex );
}
}
public static String dumpPropertiesToString( UIDefaults defaults ) {
Properties properties = (Properties) defaults.get( KEY_PROPERTIES );
if( properties == null )
return null;
// dump to string
StringWriter stringWriter = new StringWriter( 100000 );
PrintWriter out = new PrintWriter( stringWriter );
out.printf( "@baseTheme = %s%n", FlatLaf.isLafDark() ? "dark" : "light" );
AtomicReference<String> lastPrefix = new AtomicReference<>();
properties.entrySet().stream()
.sorted( (e1, e2) -> ((String)e1.getKey()).compareTo( (String) e2.getKey() ) )
.forEach( e -> {
String key = (String) e.getKey();
String value = (String) e.getValue();
String prefix = keyPrefix( key );
if( !prefix.equals( lastPrefix.get() ) ) {
lastPrefix.set( prefix );
out.printf( "%n%n#---- %s ----%n%n", prefix );
}
out.printf( "%-50s = %s%n", key, value.replace( ";", "; \\\n\t" ) );
} );
return stringWriter.toString().replace( "\r", "" );
}
private static String keyPrefix( String key ) {
int dotIndex = key.indexOf( '.' );
return (dotIndex > 0)
? key.substring( 0, dotIndex )
: key.endsWith( "UI" )
? key.substring( 0, key.length() - 2 )
: "";
}
}

View File

@@ -276,20 +276,21 @@ public class IJThemesPanel
return;
EventQueue.invokeLater( () -> {
setTheme( themeInfo );
setTheme( themeInfo, false );
} );
}
private void setTheme( IJThemeInfo themeInfo ) {
private void setTheme( IJThemeInfo themeInfo, boolean reload ) {
if( themeInfo == null )
return;
// change look and feel
if( themeInfo.lafClassName != null ) {
if( themeInfo.lafClassName.equals( UIManager.getLookAndFeel().getClass().getName() ) )
if( !reload && themeInfo.lafClassName.equals( UIManager.getLookAndFeel().getClass().getName() ) )
return;
FlatAnimatedLafChange.showSnapshot();
if( !reload )
FlatAnimatedLafChange.showSnapshot();
try {
UIManager.setLookAndFeel( themeInfo.lafClassName );
@@ -298,7 +299,8 @@ public class IJThemesPanel
showInformationDialog( "Failed to create '" + themeInfo.lafClassName + "'.", ex );
}
} else if( themeInfo.themeFile != null ) {
FlatAnimatedLafChange.showSnapshot();
if( !reload )
FlatAnimatedLafChange.showSnapshot();
try {
if( themeInfo.themeFile.getName().endsWith( ".properties" ) )
@@ -320,7 +322,9 @@ public class IJThemesPanel
// update all components
FlatLaf.updateUI();
FlatAnimatedLafChange.hideSnapshotWithAnimation();
if( !reload )
FlatAnimatedLafChange.hideSnapshotWithAnimation();
}
private void browsePlugin() {
@@ -386,8 +390,8 @@ public class IJThemesPanel
// use invokeLater() because KEY_LAF_THEME_FILE is updated after this event
EventQueue.invokeLater( () -> {
selectedCurrentLookAndFeel();
lastLafChangeTime = System.currentTimeMillis();
} );
lastLafChangeTime = System.currentTimeMillis();
}
}
@@ -435,7 +439,7 @@ public class IJThemesPanel
}
if( reload )
setTheme( themesList.getSelectedValue() );
setTheme( themesList.getSelectedValue(), true );
}
}
}

View File

@@ -76,7 +76,7 @@
+ ProgressBar.foreground #c4c4c4 HSL 0 0 77 javax.swing.plaf.ColorUIResource [UI]
- ProgressBar.selectionForeground #eeeeee HSL 0 0 93 javax.swing.plaf.ColorUIResource [UI]
+ ProgressBar.selectionForeground #3c3f41 HSL 204 4 25 javax.swing.plaf.ColorUIResource [UI]
+ ProgressBar.selectionForeground #1e2021 HSL 200 5 12 javax.swing.plaf.ColorUIResource [UI]
#---- RadioButton ----
@@ -121,4 +121,4 @@
+ contrast ratio: ProgressBar.foreground #c4c4c4 #3c3f41 6.1 !
- contrast ratio: ProgressBar.selectionForeground #eeeeee #4c87c8 3.2 !!!!
+ contrast ratio: ProgressBar.selectionForeground #3c3f41 #c4c4c4 6.1 !
+ contrast ratio: ProgressBar.selectionForeground #1e2021 #c4c4c4 9.4

View File

@@ -60,6 +60,7 @@ import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicLookAndFeel;
import javax.swing.table.JTableHeader;
import com.formdev.flatlaf.*;
import com.formdev.flatlaf.demo.intellijthemes.IJThemesDump;
import com.formdev.flatlaf.intellijthemes.FlatAllIJThemes;
import com.formdev.flatlaf.testing.FlatTestLaf;
import com.formdev.flatlaf.themes.*;
@@ -155,6 +156,8 @@ public class UIDefaultsDump
private static void dumpIntelliJThemes( File dir ) {
dir = new File( dir, "intellijthemes" );
IJThemesDump.enablePropertiesRecording();
for( LookAndFeelInfo info : FlatAllIJThemes.INFOS ) {
String lafClassName = info.getClassName();
String relativeLafClassName = StringUtils.removeLeading( lafClassName, "com.formdev.flatlaf.intellijthemes." );
@@ -192,6 +195,15 @@ public class UIDefaultsDump
dump( dir, "_InputMap", lookAndFeel, defaults, key -> key.contains( "InputMap" ), false );
dumpActionMaps( dir, "_ActionMap", lookAndFeel, defaults );
}
if( lookAndFeel instanceof IntelliJTheme.ThemeLaf ) {
File cdir = new File( dir.getPath().replace( "intellijthemes", "intellijthemes-colors" ) );
dumpColorsToProperties( cdir, lookAndFeel, defaults );
// dump as .properties
File pdir = new File( dir.getPath().replace( "intellijthemes", "intellijthemes-properties" ) );
IJThemesDump.dumpProperties( pdir, lookAndFeel.getClass().getSimpleName(), defaults );
}
}
private static void dump( File dir, String nameSuffix,
@@ -231,8 +243,8 @@ public class UIDefaultsDump
if( origFile != null ) {
try {
Map<String, String> defaults1 = parse( new InputStreamReader(
new FileInputStream( origFile ), StandardCharsets.UTF_8 ) );
Map<String, String> defaults2 = parse( new StringReader( stringWriter.toString() ) );
new FileInputStream( origFile ), StandardCharsets.UTF_8 ), false );
Map<String, String> defaults2 = parse( new StringReader( stringWriter.toString() ), false );
content = diff( defaults1, defaults2 );
} catch( Exception ex ) {
@@ -280,6 +292,45 @@ public class UIDefaultsDump
}
}
private static void dumpColorsToProperties( File dir, LookAndFeel lookAndFeel, UIDefaults defaults ) {
// dump to string
StringWriter stringWriter = new StringWriter( 100000 );
new UIDefaultsDump( lookAndFeel, defaults ).dumpColorsAsProperties( new PrintWriter( stringWriter ) );
String name = lookAndFeel instanceof MyBasicLookAndFeel
? BasicLookAndFeel.class.getSimpleName()
: lookAndFeel.getClass().getSimpleName();
File file = new File( dir, name + ".properties" );
// build and append differences
if( file.exists() ) {
try {
Map<String, String> defaults1 = parse( new InputStreamReader(
new FileInputStream( file ), StandardCharsets.UTF_8 ), true );
Map<String, String> defaults2 = parse( new StringReader( stringWriter.toString() ), true );
String diff = diff( defaults1, defaults2 );
if( !diff.isEmpty() ) {
stringWriter.write( "\n\n\n\n#==== Differences ==============================================================\n\n" );
stringWriter.write( diff );
}
} catch( Exception ex ) {
ex.printStackTrace();
return;
}
}
// write to file
file.getParentFile().mkdirs();
try( Writer fileWriter = new OutputStreamWriter(
new FileOutputStream( file ), StandardCharsets.UTF_8 ) )
{
fileWriter.write( stringWriter.toString().replace( "\r", "" ) );
} catch( IOException ex ) {
ex.printStackTrace();
}
}
private static String diff( Map<String, String> defaults1, Map<String, String> defaults2 ) {
TreeSet<String> keys = new TreeSet<>();
keys.addAll( defaults1.keySet() );
@@ -355,7 +406,7 @@ public class UIDefaultsDump
buf.append( '\n' );
}
private static Map<String, String> parse( Reader in ) throws IOException {
private static Map<String, String> parse( Reader in, boolean ignoreDiffs ) throws IOException {
Map<String, String> defaults = new LinkedHashMap<>();
try( BufferedReader reader = new BufferedReader( in ) ) {
String lastKey = null;
@@ -371,6 +422,9 @@ public class UIDefaultsDump
continue;
}
if( ignoreDiffs && (trimmedLine.startsWith( "- " ) || trimmedLine.startsWith( "+ " )) )
continue;
if( Character.isWhitespace( line.charAt( 0 ) ) ) {
String value = defaults.get( lastKey );
value += '\n' + line;
@@ -443,6 +497,30 @@ public class UIDefaultsDump
dumpContrastRatios( out );
}
private void dumpColorsAsProperties( PrintWriter out ) {
defaults.keySet().stream()
.sorted( (key1, key2) -> {
return String.valueOf( key1 ).compareTo( String.valueOf( key2 ) );
} )
.forEach( key -> {
Color color = defaults.getColor( key );
if( color == null )
return;
String strKey = String.valueOf( key );
String prefix = keyPrefix( strKey );
if( !prefix.equals( lastPrefix ) ) {
lastPrefix = prefix;
out.printf( "%n%n#---- %s ----%n%n", prefix );
}
out.printf( "%-50s = #%06x", strKey, color.getRGB() & 0xffffff );
if( color.getAlpha() != 255 )
out.printf( "%02x", (color.getRGB() >> 24) & 0xff );
out.println();
} );
}
private void dumpActionMaps( PrintWriter out ) {
dumpHeader( out );