mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-12 23:07:15 -06:00
IntelliJ Themes: reworked applying values so that it works and behaves the same way as in IntelliJ Platform
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf;
|
package com.formdev.flatlaf;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
@@ -23,9 +24,11 @@ import java.io.Reader;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.swing.UIDefaults;
|
import javax.swing.UIDefaults;
|
||||||
|
import javax.swing.plaf.ColorUIResource;
|
||||||
import com.formdev.flatlaf.json.Json;
|
import com.formdev.flatlaf.json.Json;
|
||||||
import com.formdev.flatlaf.json.ParseException;
|
import com.formdev.flatlaf.json.ParseException;
|
||||||
|
|
||||||
@@ -42,6 +45,8 @@ public class IntelliJTheme
|
|||||||
private final Map<String, Object> ui;
|
private final Map<String, Object> ui;
|
||||||
private final Map<String, Object> icons;
|
private final Map<String, Object> icons;
|
||||||
|
|
||||||
|
private Map<String, Color> namedColors = Collections.emptyMap();
|
||||||
|
|
||||||
public static boolean install( InputStream in )
|
public static boolean install( InputStream in )
|
||||||
throws IOException, ParseException
|
throws IOException, ParseException
|
||||||
{
|
{
|
||||||
@@ -86,62 +91,69 @@ public class IntelliJTheme
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void applyProperties( UIDefaults defaults ) {
|
private void applyProperties( UIDefaults defaults ) {
|
||||||
Map<String, String> properties = convertToProperties();
|
if( ui == null )
|
||||||
applyProperties( properties, defaults );
|
return;
|
||||||
|
|
||||||
|
loadColorPalette( defaults );
|
||||||
|
|
||||||
|
// convert Json "ui" structure to UI defaults
|
||||||
|
ArrayList<Object> defaultsKeysCache = new ArrayList<>();
|
||||||
|
for( Map.Entry<String, Object> e : ui.entrySet() )
|
||||||
|
apply( e.getKey(), e.getValue(), defaults, defaultsKeysCache );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void applyProperties( Map<String, String> properties, UIDefaults defaults ) {
|
private void loadColorPalette( UIDefaults defaults ) {
|
||||||
// globals
|
if( colors == null )
|
||||||
ArrayList<Object> keys = Collections.list( defaults.keys() );
|
return;
|
||||||
for( Map.Entry<String, String> e : properties.entrySet() ) {
|
|
||||||
String key = e.getKey();
|
|
||||||
if( !key.startsWith( "*." ) )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
String tail = key.substring( 1 );
|
namedColors = new HashMap<>();
|
||||||
Object uiValue = UIDefaultsLoader.parseValue( key, e.getValue() );
|
|
||||||
for( Object k : keys ) {
|
for( Map.Entry<String, String> e : colors.entrySet() ) {
|
||||||
if( k instanceof String && ((String)k).endsWith( tail ) )
|
String value = e.getValue();
|
||||||
defaults.put( k, uiValue );
|
ColorUIResource color = UIDefaultsLoader.parseColor( value );
|
||||||
|
if( color != null ) {
|
||||||
|
String key = e.getKey();
|
||||||
|
namedColors.put( key, color );
|
||||||
|
defaults.put( "ColorPalette." + e.getKey(), color );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// non-globals
|
|
||||||
for( Map.Entry<String, String> e : properties.entrySet() ) {
|
|
||||||
String key = e.getKey();
|
|
||||||
if( key.startsWith( "*." ) )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Object uiValue = UIDefaultsLoader.parseValue( key, e.getValue() );
|
|
||||||
defaults.put( key, uiValue );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, String> convertToProperties() {
|
|
||||||
Map<String, String> properties = new LinkedHashMap<>();
|
|
||||||
if( ui == null )
|
|
||||||
return properties;
|
|
||||||
|
|
||||||
// convert json structure to properties map
|
|
||||||
for( Map.Entry<String, Object> e : ui.entrySet() )
|
|
||||||
addToProperties( e.getKey(), e.getValue(), properties );
|
|
||||||
|
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings( "unchecked" )
|
@SuppressWarnings( "unchecked" )
|
||||||
private void addToProperties( String key, Object value, Map<String, String> properties ) {
|
private void apply( String key, Object value, UIDefaults defaults, ArrayList<Object> defaultsKeysCache ) {
|
||||||
if( value instanceof Map ) {
|
if( value instanceof Map ) {
|
||||||
for( Map.Entry<String, Object> e : ((Map<String, Object>)value).entrySet() )
|
for( Map.Entry<String, Object> e : ((Map<String, Object>)value).entrySet() )
|
||||||
addToProperties( key + '.' + e.getKey(), e.getValue(), properties );
|
apply( key + '.' + e.getKey(), e.getValue(), defaults, defaultsKeysCache );
|
||||||
} else {
|
} else {
|
||||||
String valueStr = value.toString();
|
String valueStr = value.toString();
|
||||||
|
|
||||||
// map colors
|
// map named colors
|
||||||
if( colors != null )
|
Object uiValue = namedColors.get( valueStr );
|
||||||
valueStr = colors.getOrDefault( valueStr, valueStr );
|
|
||||||
|
|
||||||
properties.put( key, valueStr );
|
// parse value
|
||||||
|
if( uiValue == null )
|
||||||
|
uiValue = UIDefaultsLoader.parseValue( key, valueStr );
|
||||||
|
|
||||||
|
if( key.startsWith( "*." ) ) {
|
||||||
|
// wildcard
|
||||||
|
String tail = key.substring( 1 );
|
||||||
|
|
||||||
|
// 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 instanceof String && ((String)k).endsWith( tail ) )
|
||||||
|
defaults.put( k, uiValue );
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
defaults.put( key, uiValue );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -229,12 +229,12 @@ class UIDefaultsLoader
|
|||||||
case ICON: return parseInstance( value );
|
case ICON: return parseInstance( value );
|
||||||
case INSETS: return parseInsets( value );
|
case INSETS: return parseInsets( value );
|
||||||
case SIZE: return parseSize( value );
|
case SIZE: return parseSize( value );
|
||||||
case COLOR: return parseColor( value, true );
|
case COLOR: return parseColorOrFunction( value, true );
|
||||||
case SCALEDNUMBER: return parseScaledNumber( value );
|
case SCALEDNUMBER: return parseScaledNumber( value );
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
default:
|
default:
|
||||||
// colors
|
// colors
|
||||||
ColorUIResource color = parseColor( value, false );
|
ColorUIResource color = parseColorOrFunction( value, false );
|
||||||
if( color != null )
|
if( color != null )
|
||||||
return color;
|
return color;
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ class UIDefaultsLoader
|
|||||||
List<String> parts = split( value, ',' );
|
List<String> parts = split( value, ',' );
|
||||||
Insets insets = parseInsets( value );
|
Insets insets = parseInsets( value );
|
||||||
ColorUIResource lineColor = (parts.size() == 5)
|
ColorUIResource lineColor = (parts.size() == 5)
|
||||||
? parseColor( resolver.apply( parts.get( 4 ) ), true )
|
? parseColorOrFunction( resolver.apply( parts.get( 4 ) ), true )
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return (LazyValue) t -> {
|
return (LazyValue) t -> {
|
||||||
@@ -301,10 +301,18 @@ class UIDefaultsLoader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ColorUIResource parseColor( String value, boolean reportError ) {
|
private static ColorUIResource parseColorOrFunction( String value, boolean reportError ) {
|
||||||
if( value.endsWith( ")" ) )
|
if( value.endsWith( ")" ) )
|
||||||
return parseColorFunctions( value, reportError );
|
return parseColorFunctions( value, reportError );
|
||||||
|
|
||||||
|
return parseColor( value, reportError );
|
||||||
|
}
|
||||||
|
|
||||||
|
static ColorUIResource parseColor( String value ) {
|
||||||
|
return parseColor( value, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ColorUIResource parseColor( String value, boolean reportError ) {
|
||||||
if( value.startsWith( "#" ) )
|
if( value.startsWith( "#" ) )
|
||||||
value = value.substring( 1 );
|
value = value.substring( 1 );
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user