mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-10 22:17:13 -06:00
Theme Editor: support color preview for color functions
UIDefaultsLoader: made some private methods package private and return parsed valued type
This commit is contained in:
@@ -167,7 +167,8 @@ class UIDefaultsLoader
|
||||
|
||||
String value = resolveValue( properties, (String) e.getValue() );
|
||||
try {
|
||||
globals.put( key.substring( GLOBAL_PREFIX.length() ), parseValue( key, value, resolver, addonClassLoaders ) );
|
||||
globals.put( key.substring( GLOBAL_PREFIX.length() ),
|
||||
parseValue( key, value, null, resolver, addonClassLoaders ) );
|
||||
} catch( RuntimeException ex ) {
|
||||
logParseError( Level.SEVERE, key, value, ex );
|
||||
}
|
||||
@@ -192,7 +193,7 @@ class UIDefaultsLoader
|
||||
|
||||
String value = resolveValue( properties, (String) e.getValue() );
|
||||
try {
|
||||
defaults.put( key, parseValue( key, value, resolver, addonClassLoaders ) );
|
||||
defaults.put( key, parseValue( key, value, null, resolver, addonClassLoaders ) );
|
||||
} catch( RuntimeException ex ) {
|
||||
logParseError( Level.SEVERE, key, value, ex );
|
||||
}
|
||||
@@ -206,7 +207,7 @@ class UIDefaultsLoader
|
||||
FlatLaf.LOG.log( level, "FlatLaf: Failed to parse: '" + key + '=' + value + '\'', ex );
|
||||
}
|
||||
|
||||
private static String resolveValue( Properties properties, String value ) {
|
||||
static String resolveValue( Properties properties, String value ) {
|
||||
if( value.startsWith( PROPERTY_PREFIX ) )
|
||||
value = value.substring( PROPERTY_PREFIX.length() );
|
||||
else if( !value.startsWith( VARIABLE_PREFIX ) )
|
||||
@@ -229,26 +230,34 @@ class UIDefaultsLoader
|
||||
return resolveValue( properties, newValue );
|
||||
}
|
||||
|
||||
private enum ValueType { UNKNOWN, STRING, CHARACTER, INTEGER, FLOAT, BORDER, ICON, INSETS, DIMENSION, COLOR,
|
||||
SCALEDINTEGER, SCALEDFLOAT, SCALEDINSETS, SCALEDDIMENSION, INSTANCE, CLASS, GRAYFILTER }
|
||||
enum ValueType { UNKNOWN, STRING, BOOLEAN, CHARACTER, INTEGER, FLOAT, BORDER, ICON, INSETS, DIMENSION, COLOR,
|
||||
SCALEDINTEGER, SCALEDFLOAT, SCALEDINSETS, SCALEDDIMENSION, INSTANCE, CLASS, GRAYFILTER, NULL, LAZY }
|
||||
|
||||
private static ValueType[] tempResultValueType = new ValueType[1];
|
||||
|
||||
static Object parseValue( String key, String value ) {
|
||||
return parseValue( key, value, v -> v, Collections.emptyList() );
|
||||
return parseValue( key, value, null, v -> v, Collections.emptyList() );
|
||||
}
|
||||
|
||||
private static Object parseValue( String key, String value, Function<String, String> resolver, List<ClassLoader> addonClassLoaders ) {
|
||||
static Object parseValue( String key, String value, ValueType[] resultValueType,
|
||||
Function<String, String> resolver, List<ClassLoader> addonClassLoaders )
|
||||
{
|
||||
if( resultValueType == null )
|
||||
resultValueType = tempResultValueType;
|
||||
|
||||
value = value.trim();
|
||||
|
||||
// null, false, true
|
||||
switch( value ) {
|
||||
case "null": return null;
|
||||
case "false": return false;
|
||||
case "true": return true;
|
||||
case "null": resultValueType[0] = ValueType.NULL; return null;
|
||||
case "false": resultValueType[0] = ValueType.BOOLEAN; return false;
|
||||
case "true": resultValueType[0] = ValueType.BOOLEAN; return true;
|
||||
}
|
||||
|
||||
// check for function "lazy"
|
||||
// Syntax: lazy(uiKey)
|
||||
if( value.startsWith( "lazy(" ) && value.endsWith( ")" ) ) {
|
||||
resultValueType[0] = ValueType.LAZY;
|
||||
String uiKey = value.substring( 5, value.length() - 1 ).trim();
|
||||
return (LazyValue) t -> {
|
||||
return lazyUIManagerGet( uiKey );
|
||||
@@ -301,6 +310,8 @@ class UIDefaultsLoader
|
||||
valueType = ValueType.GRAYFILTER;
|
||||
}
|
||||
|
||||
resultValueType[0] = valueType;
|
||||
|
||||
// parse value
|
||||
switch( valueType ) {
|
||||
case STRING: return value;
|
||||
@@ -323,20 +334,27 @@ class UIDefaultsLoader
|
||||
default:
|
||||
// colors
|
||||
Object color = parseColorOrFunction( value, resolver, false );
|
||||
if( color != null )
|
||||
if( color != null ) {
|
||||
resultValueType[0] = ValueType.COLOR;
|
||||
return color;
|
||||
}
|
||||
|
||||
// integer
|
||||
Integer integer = parseInteger( value, false );
|
||||
if( integer != null )
|
||||
if( integer != null ) {
|
||||
resultValueType[0] = ValueType.INTEGER;
|
||||
return integer;
|
||||
}
|
||||
|
||||
// float
|
||||
Float f = parseFloat( value, false );
|
||||
if( f != null )
|
||||
if( f != null ) {
|
||||
resultValueType[0] = ValueType.FLOAT;
|
||||
return f;
|
||||
}
|
||||
|
||||
// string
|
||||
resultValueType[0] = ValueType.STRING;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,5 +21,5 @@ plugins {
|
||||
dependencies {
|
||||
implementation( project( ":flatlaf-core" ) )
|
||||
|
||||
implementation( "com.fifesoft:rsyntaxtextarea:3.1.0" )
|
||||
implementation( "com.fifesoft:rsyntaxtextarea:3.1.1" )
|
||||
}
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Function;
|
||||
import com.formdev.flatlaf.UIDefaultsLoader.ValueType;
|
||||
|
||||
/**
|
||||
* Enable accessing package private methods of {@link UIDefaultsLoader}.
|
||||
*
|
||||
@@ -23,6 +28,40 @@ package com.formdev.flatlaf;
|
||||
*/
|
||||
public class UIDefaultsLoaderAccessor
|
||||
{
|
||||
public static Object UNKNOWN = ValueType.UNKNOWN;
|
||||
public static Object STRING = ValueType.STRING;
|
||||
public static Object BOOLEAN = ValueType.BOOLEAN;
|
||||
public static Object CHARACTER = ValueType.CHARACTER;
|
||||
public static Object INTEGER = ValueType.INTEGER;
|
||||
public static Object FLOAT = ValueType.FLOAT;
|
||||
public static Object BORDER = ValueType.BORDER;
|
||||
public static Object ICON = ValueType.ICON;
|
||||
public static Object INSETS = ValueType.INSETS;
|
||||
public static Object DIMENSION = ValueType.DIMENSION;
|
||||
public static Object COLOR = ValueType.COLOR;
|
||||
public static Object SCALEDINTEGER = ValueType.SCALEDINTEGER;
|
||||
public static Object SCALEDFLOAT = ValueType.SCALEDFLOAT;
|
||||
public static Object SCALEDINSETS = ValueType.SCALEDINSETS;
|
||||
public static Object SCALEDDIMENSION = ValueType.SCALEDDIMENSION;
|
||||
public static Object INSTANCE = ValueType.INSTANCE;
|
||||
public static Object CLASS = ValueType.CLASS;
|
||||
public static Object GRAYFILTER = ValueType.GRAYFILTER;
|
||||
public static Object NULL = ValueType.NULL;
|
||||
public static Object LAZY = ValueType.LAZY;
|
||||
|
||||
public static String resolveValue( Properties properties, String value ) {
|
||||
return UIDefaultsLoader.resolveValue( properties, value );
|
||||
}
|
||||
|
||||
public static Object parseValue( String key, String value, Object[] resultValueType,
|
||||
Function<String, String> resolver )
|
||||
{
|
||||
ValueType[] resultValueType2 = new ValueType[1];
|
||||
Object result = UIDefaultsLoader.parseValue( key, value, resultValueType2, resolver, Collections.emptyList() );
|
||||
resultValueType[0] = resultValueType2[0];
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int parseColorRGBA( String value ) {
|
||||
return UIDefaultsLoader.parseColorRGBA( value );
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ class FlatSyntaxTextArea
|
||||
{
|
||||
private boolean useColorOfColorTokens;
|
||||
|
||||
final FlatThemePropertiesSupport propertiesSupport = new FlatThemePropertiesSupport( this );
|
||||
private final Map<String, Color> parsedColorsMap = new HashMap<>();
|
||||
|
||||
FlatSyntaxTextArea() {
|
||||
|
||||
@@ -103,11 +103,18 @@ class FlatThemeEditorOverlay
|
||||
g.setColor( color );
|
||||
g.fillRect( px, r.y, pw, r.height );
|
||||
|
||||
// if color is semi-transparent paint also none-transparent color
|
||||
int alpha = color.getAlpha();
|
||||
if( alpha != 255 && pw > r.height * 2 ) {
|
||||
g.setColor( new Color( color.getRGB() ) );
|
||||
g.fillRect( px + pw - r.height, r.y, r.height, r.height );
|
||||
}
|
||||
|
||||
// paint text
|
||||
int textX = px - maxTextWidth;
|
||||
if( textX > r.x + gap) {
|
||||
float[] hsl = HSLColor.fromRGB( color );
|
||||
String hslStr = String.format( "HSL %d %d %d",
|
||||
String hslStr = String.format( "HSL %3d %2d %2d",
|
||||
Math.round( hsl[0] ), Math.round( hsl[1] ), Math.round( hsl[2] ) );
|
||||
g.setColor( textArea.getForeground() );
|
||||
FlatUIUtils.drawString( textArea, g, hslStr, textX,
|
||||
@@ -120,6 +127,10 @@ class FlatThemeEditorOverlay
|
||||
}
|
||||
|
||||
private Color getColorInLine( FlatSyntaxTextArea textArea, int line ) {
|
||||
Object value = textArea.propertiesSupport.getParsedValueAtLine( line );
|
||||
if( value instanceof Color )
|
||||
return (Color) value;
|
||||
|
||||
Token token = textArea.getTokenListForLine( line );
|
||||
for( Token t = token; t != null && t.isPaintable(); t = t.getNextToken() ) {
|
||||
if( t.getType() == FlatThemeTokenMaker.TOKEN_COLOR ) {
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2020 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.themeeditor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Function;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import com.formdev.flatlaf.UIDefaultsLoaderAccessor;
|
||||
|
||||
/**
|
||||
* Supports parsing content of text area in FlatLaf properties syntax.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
class FlatThemePropertiesSupport
|
||||
implements DocumentListener
|
||||
{
|
||||
private final FlatSyntaxTextArea textArea;
|
||||
private final Function<String, String> resolver;
|
||||
private Properties propertiesCache;
|
||||
private final Map<Integer, Object> parsedValueCache = new HashMap<>();
|
||||
|
||||
FlatThemePropertiesSupport( FlatSyntaxTextArea textArea ) {
|
||||
this.textArea = textArea;
|
||||
|
||||
resolver = v -> {
|
||||
return resolveValue( v );
|
||||
};
|
||||
|
||||
textArea.getDocument().addDocumentListener( this );
|
||||
}
|
||||
|
||||
private String resolveValue( String value ) {
|
||||
return UIDefaultsLoaderAccessor.resolveValue( getProperties(), value );
|
||||
}
|
||||
|
||||
Object getParsedValueAtLine( int line ) {
|
||||
Integer lineKey = line;
|
||||
Object parsedValue = parsedValueCache.get( lineKey );
|
||||
if( parsedValue != null )
|
||||
return !(parsedValue instanceof Exception) ? parsedValue : null;
|
||||
|
||||
KeyValue keyValue = getKeyValueAtLine( line );
|
||||
if( keyValue == null )
|
||||
return null;
|
||||
|
||||
try {
|
||||
Object[] resultValueType = new Object[1];
|
||||
String value = resolveValue( keyValue.value );
|
||||
parsedValue = UIDefaultsLoaderAccessor.parseValue( keyValue.key, value, resultValueType, resolver );
|
||||
parsedValueCache.put( lineKey, parsedValue );
|
||||
return parsedValue;
|
||||
} catch( Exception ex ) {
|
||||
System.out.println( ex.getMessage() ); //TODO
|
||||
parsedValueCache.put( lineKey, ex );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private KeyValue getKeyValueAtLine( int line ) {
|
||||
try {
|
||||
int startOffset = textArea.getLineStartOffset( line );
|
||||
int endOffset = textArea.getLineEndOffset( line );
|
||||
String text = textArea.getText( startOffset, endOffset - startOffset );
|
||||
|
||||
Properties properties = new Properties();
|
||||
properties.load( new StringReader( text ) );
|
||||
if( properties.isEmpty() )
|
||||
return null;
|
||||
|
||||
String key = (String) properties.keys().nextElement();
|
||||
String value = properties.getProperty( key );
|
||||
return new KeyValue( key, value );
|
||||
} catch( BadLocationException | IOException ex ) {
|
||||
// ignore
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Properties getProperties() {
|
||||
if( propertiesCache != null )
|
||||
return propertiesCache;
|
||||
|
||||
propertiesCache = new Properties();
|
||||
try {
|
||||
propertiesCache.load( new StringReader( textArea.getText() ) );
|
||||
} catch( IOException ex ) {
|
||||
ex.printStackTrace(); //TODO
|
||||
}
|
||||
return propertiesCache;
|
||||
}
|
||||
|
||||
private void clearCache() {
|
||||
propertiesCache = null;
|
||||
parsedValueCache.clear();
|
||||
}
|
||||
|
||||
//---- interface DocumentListener ----
|
||||
|
||||
@Override
|
||||
public void insertUpdate( DocumentEvent e ) {
|
||||
clearCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUpdate( DocumentEvent e ) {
|
||||
clearCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate( DocumentEvent e ) {
|
||||
}
|
||||
|
||||
//---- class KeyValue -----------------------------------------------------
|
||||
|
||||
static class CacheLineInfo {
|
||||
Object parsedValue;
|
||||
Object valueType;
|
||||
Exception parseError;
|
||||
|
||||
Color origColor;
|
||||
}
|
||||
|
||||
//---- class KeyValue -----------------------------------------------------
|
||||
|
||||
static class KeyValue {
|
||||
final String key;
|
||||
final String value;
|
||||
|
||||
KeyValue( String key, String value ) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,8 +33,8 @@ Prop.lazy=lazy(Prop.string)
|
||||
|
||||
Prop.colorFunc1=rgb(12,34,56)
|
||||
Prop.colorFunc2=rgba(12,34,56,78)
|
||||
Prop.colorFunc3=hsl(12,34,56)
|
||||
Prop.colorFunc4=hsla(12,34,56,78)
|
||||
Prop.colorFunc3=hsl(12,34%,56%)
|
||||
Prop.colorFunc4=hsla(12,34%,56%,78%)
|
||||
|
||||
Prop.colorFunc5=lighten(#fe1289,20%)
|
||||
Prop.colorFunc6=darken(#fe1289,20%)
|
||||
|
||||
Reference in New Issue
Block a user