Button: hover and pressed background colors are now derived from actual button background color (issue #21)

This commit is contained in:
Karl Tauber
2019-10-27 11:03:40 +01:00
parent ec572436a9
commit 2ec142f000
11 changed files with 700 additions and 35 deletions

View File

@@ -10,6 +10,8 @@ FlatLaf Change Log
`JPasswordField`, `JScrollPane` and `JTextField` are non-opaque if they have `JPasswordField`, `JScrollPane` and `JTextField` are non-opaque if they have
an outside focus border (e.g. IntelliJ and Darcula themes). (issues #20 and an outside focus border (e.g. IntelliJ and Darcula themes). (issues #20 and
#17) #17)
- Button: Hover and pressed background colors are now derived from actual button
background color. (issue #21)
## 0.16 ## 0.16

View File

@@ -36,6 +36,8 @@ import javax.swing.plaf.DimensionUIResource;
import javax.swing.plaf.InsetsUIResource; import javax.swing.plaf.InsetsUIResource;
import com.formdev.flatlaf.ui.FlatEmptyBorder; import com.formdev.flatlaf.ui.FlatEmptyBorder;
import com.formdev.flatlaf.ui.FlatLineBorder; import com.formdev.flatlaf.ui.FlatLineBorder;
import com.formdev.flatlaf.util.ColorFunctions;
import com.formdev.flatlaf.util.DerivedColor;
import com.formdev.flatlaf.util.ScaledNumber; import com.formdev.flatlaf.util.ScaledNumber;
/** /**
@@ -101,7 +103,11 @@ class UIDefaultsLoader
continue; continue;
String value = resolveValue( properties, (String) e.getValue() ); String value = resolveValue( properties, (String) e.getValue() );
try {
globals.put( key.substring( GLOBAL_PREFIX.length() ), parseValue( key, value, resolver ) ); globals.put( key.substring( GLOBAL_PREFIX.length() ), parseValue( key, value, resolver ) );
} catch( RuntimeException ex ) {
logParseError( key, value, ex );
}
} }
// override UI defaults with globals // override UI defaults with globals
@@ -122,13 +128,22 @@ class UIDefaultsLoader
continue; continue;
String value = resolveValue( properties, (String) e.getValue() ); String value = resolveValue( properties, (String) e.getValue() );
try {
defaults.put( key, parseValue( key, value, resolver ) ); defaults.put( key, parseValue( key, value, resolver ) );
} catch( RuntimeException ex ) {
logParseError( key, value, ex );
}
} }
} catch( IOException ex ) { } catch( IOException ex ) {
ex.printStackTrace(); ex.printStackTrace();
} }
} }
private static void logParseError( String key, String value, RuntimeException ex ) {
System.err.println( "Failed to parse: '" + key + '=' + value + '\'' );
System.err.println( " " + ex.getMessage() );
}
private static String resolveValue( Properties properties, String value ) { private static String resolveValue( Properties properties, String value ) {
if( !value.startsWith( VARIABLE_PREFIX ) ) if( !value.startsWith( VARIABLE_PREFIX ) )
return value; return value;
@@ -147,8 +162,7 @@ class UIDefaultsLoader
if( optional ) if( optional )
return "null"; return "null";
System.err.println( "variable or reference '" + value + "' not found" ); throw new IllegalArgumentException( "variable or reference '" + value + "' not found" );
throw new IllegalArgumentException( value );
} }
return resolveValue( properties, newValue ); return resolveValue( properties, newValue );
@@ -264,8 +278,7 @@ class UIDefaultsLoader
Integer.parseInt( numbers.get( 2 ) ), Integer.parseInt( numbers.get( 2 ) ),
Integer.parseInt( numbers.get( 3 ) ) ); Integer.parseInt( numbers.get( 3 ) ) );
} catch( NumberFormatException ex ) { } catch( NumberFormatException ex ) {
System.err.println( "invalid insets '" + value + "'" ); throw new IllegalArgumentException( "invalid insets '" + value + "'" );
throw ex;
} }
} }
@@ -276,12 +289,14 @@ class UIDefaultsLoader
Integer.parseInt( numbers.get( 0 ) ), Integer.parseInt( numbers.get( 0 ) ),
Integer.parseInt( numbers.get( 1 ) ) ); Integer.parseInt( numbers.get( 1 ) ) );
} catch( NumberFormatException ex ) { } catch( NumberFormatException ex ) {
System.err.println( "invalid size '" + value + "'" ); throw new IllegalArgumentException( "invalid size '" + value + "'" );
throw ex;
} }
} }
private static ColorUIResource parseColor( String value, boolean reportError ) { private static ColorUIResource parseColor( String value, boolean reportError ) {
if( value.endsWith( ")" ) )
return parseColorFunctions( value, reportError );
try { try {
int rgb = Integer.parseInt( value, 16 ); int rgb = Integer.parseInt( value, 16 );
if( value.length() == 6 ) if( value.length() == 6 )
@@ -292,23 +307,78 @@ class UIDefaultsLoader
if( reportError ) if( reportError )
throw new NumberFormatException( value ); throw new NumberFormatException( value );
} catch( NumberFormatException ex ) { } catch( NumberFormatException ex ) {
if( reportError ) { if( reportError )
System.err.println( "invalid color '" + value + "'" ); throw new IllegalArgumentException( "invalid color '" + value + "'" );
throw ex;
}
// not a color --> ignore // not a color --> ignore
} }
return null; return null;
} }
private static ColorUIResource parseColorFunctions( String value, boolean reportError ) {
int paramsStart = value.indexOf( '(' );
if( paramsStart < 0 ) {
if( reportError )
throw new IllegalArgumentException( "missing opening parenthesis in function '" + value + "'" );
return null;
}
String function = value.substring( 0, paramsStart ).trim();
List<String> params = split( value.substring( paramsStart + 1, value.length() - 1 ), ',' );
if( params.isEmpty() )
throw new IllegalArgumentException( "missing parameters in function '" + value + "'" );
switch( function ) {
case "lighten": return parseColorLightenOrDarken( true, params, reportError );
case "darken": return parseColorLightenOrDarken( false, params, reportError );
}
throw new IllegalArgumentException( "unknown color function '" + value + "'" );
}
/**
* Syntax: lighten(amount[,options]) or darken(amount[,options])
* - amount: percentage 0-100%
* - options: [relative] [autoInverse]
*/
private static ColorUIResource parseColorLightenOrDarken( boolean lighten, List<String> params, boolean reportError ) {
int amount = parsePercentage( params.get( 0 ) );
boolean relative = false;
boolean autoInverse = false;
if( params.size() >= 2 ) {
String options = params.get( 1 );
relative = options.contains( "relative" );
autoInverse = options.contains( "autoInverse" );
}
return new DerivedColor( lighten
? new ColorFunctions.Lighten( amount, relative, autoInverse )
: new ColorFunctions.Darken( amount, relative, autoInverse ) );
}
private static int parsePercentage( String value ) {
if( !value.endsWith( "%" ) )
throw new NumberFormatException( "invalid percentage '" + value + "'" );
int val;
try {
val = Integer.parseInt( value.substring( 0, value.length() - 1 ) );
} catch( NumberFormatException ex ) {
throw new NumberFormatException( "invalid percentage '" + value + "'" );
}
if( val < 0 || val > 100 )
throw new IllegalArgumentException( "percentage out of range (0-100%) '" + value + "'" );
return val;
}
private static Integer parseInteger( String value, boolean reportError ) { private static Integer parseInteger( String value, boolean reportError ) {
try { try {
return Integer.parseInt( value ); return Integer.parseInt( value );
} catch( NumberFormatException ex ) { } catch( NumberFormatException ex ) {
if( reportError ) { if( reportError )
System.err.println( "invalid integer '" + value + "'" ); throw new NumberFormatException( "invalid integer '" + value + "'" );
throw ex;
}
} }
return null; return null;
} }
@@ -317,8 +387,7 @@ class UIDefaultsLoader
try { try {
return new ScaledNumber( Integer.parseInt( value ) ); return new ScaledNumber( Integer.parseInt( value ) );
} catch( NumberFormatException ex ) { } catch( NumberFormatException ex ) {
System.err.println( "invalid integer '" + value + "'" ); throw new NumberFormatException( "invalid integer '" + value + "'" );
throw ex;
} }
} }

View File

@@ -109,12 +109,13 @@ public class FlatCheckBoxIcon
paintBorder( g2 ); paintBorder( g2 );
// paint background // paint background
g2.setColor( FlatButtonUI.buttonStateColor( c, FlatUIUtils.setColor( g2, FlatButtonUI.buttonStateColor( c,
selected ? selectedBackground : background, selected ? selectedBackground : background,
disabledBackground, disabledBackground,
focusedBackground, focusedBackground,
selected && selectedHoverBackground != null ? selectedHoverBackground : hoverBackground, selected && selectedHoverBackground != null ? selectedHoverBackground : hoverBackground,
selected && selectedPressedBackground != null ? selectedPressedBackground : pressedBackground ) ); selected && selectedPressedBackground != null ? selectedPressedBackground : pressedBackground ),
background );
paintBackground( g2 ); paintBackground( g2 );
// paint checkmark // paint checkmark

View File

@@ -24,6 +24,7 @@ import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D; import java.awt.geom.Path2D;
import javax.swing.UIManager; import javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatButtonUI; import com.formdev.flatlaf.ui.FlatButtonUI;
import com.formdev.flatlaf.ui.FlatUIUtils;
/** /**
* Help button icon for {@link javax.swing.JButton}. * Help button icon for {@link javax.swing.JButton}.
@@ -99,12 +100,12 @@ public class FlatHelpButtonIcon
g2.fill( new Ellipse2D.Float( focusWidth + 0.5f, focusWidth + 0.5f, 21, 21 ) ); g2.fill( new Ellipse2D.Float( focusWidth + 0.5f, focusWidth + 0.5f, 21, 21 ) );
// paint background // paint background
g2.setColor( FlatButtonUI.buttonStateColor( c, FlatUIUtils.setColor( g2, FlatButtonUI.buttonStateColor( c,
background, background,
disabledBackground, disabledBackground,
focusedBackground, focusedBackground,
hoverBackground, hoverBackground,
pressedBackground ) ); pressedBackground ), background );
g2.fill( new Ellipse2D.Float( focusWidth + 1.5f, focusWidth + 1.5f, 19, 19 ) ); g2.fill( new Ellipse2D.Float( focusWidth + 1.5f, focusWidth + 1.5f, 19, 19 ) );
// paint question mark // paint question mark

View File

@@ -190,7 +190,7 @@ public class FlatButtonUI
float focusWidth = (border instanceof FlatBorder) ? scale( (float) this.focusWidth ) : 0; float focusWidth = (border instanceof FlatBorder) ? scale( (float) this.focusWidth ) : 0;
float arc = (border instanceof FlatButtonBorder || isToolBarButton( c )) ? scale( (float) this.arc ) : 0; float arc = (border instanceof FlatButtonBorder || isToolBarButton( c )) ? scale( (float) this.arc ) : 0;
g2.setColor( background ); FlatUIUtils.setColor( g2, background, isDefaultButton(c) ? defaultBackground : c.getBackground() );
FlatUIUtils.fillRoundRectangle( g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, arc ); FlatUIUtils.fillRoundRectangle( g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, arc );
} finally { } finally {
g2.dispose(); g2.dispose();

View File

@@ -38,6 +38,7 @@ import javax.swing.JComponent;
import javax.swing.LookAndFeel; import javax.swing.LookAndFeel;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.plaf.ColorUIResource; import javax.swing.plaf.ColorUIResource;
import com.formdev.flatlaf.util.DerivedColor;
import com.formdev.flatlaf.util.JavaCompatibility; import com.formdev.flatlaf.util.JavaCompatibility;
import com.formdev.flatlaf.util.UIScale; import com.formdev.flatlaf.util.UIScale;
@@ -104,6 +105,12 @@ public class FlatUIUtils
MAC_USE_QUARTZ ? RenderingHints.VALUE_STROKE_PURE : RenderingHints.VALUE_STROKE_NORMALIZE ); MAC_USE_QUARTZ ? RenderingHints.VALUE_STROKE_PURE : RenderingHints.VALUE_STROKE_NORMALIZE );
} }
public static void setColor( Graphics g, Color color, Color baseColor ) {
if( color instanceof DerivedColor )
color = ((DerivedColor)color).derive( baseColor );
g.setColor( color );
}
/** /**
* Draws a round rectangle. * Draws a round rectangle.
*/ */

View File

@@ -0,0 +1,102 @@
/*
* Copyright 2019 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
*
* http://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.util;
import java.awt.Color;
/**
* Functions that modify colors.
*
* @author Karl Tauber
*/
public class ColorFunctions
{
public static Color applyFunctions( Color color, ColorFunction[] functions ) {
float[] hsl = HSLColor.fromRGB( color );
float alpha = color.getAlpha() / 255f;
for( ColorFunction function : functions )
function.apply( hsl );
return HSLColor.toRGB( hsl, alpha );
}
private static float clamp( float value ) {
return (value < 0)
? 0
: ((value > 100)
? 100
: value);
}
//---- interface ColorFunction --------------------------------------------
public interface ColorFunction {
void apply( float[] hsl );
}
//---- class Lighten ------------------------------------------------------
/**
* Increase the lightness of a color in the HSL color space by an absolute
* or relative amount.
*/
public static class Lighten
implements ColorFunction
{
private final float amount;
private final boolean relative;
private final boolean autoInverse;
public Lighten( float amount, boolean relative, boolean autoInverse ) {
this.amount = amount;
this.relative = relative;
this.autoInverse = autoInverse;
}
@Override
public void apply( float[] hsl ) {
float amount2 = autoInverse && shouldInverse( hsl ) ? -amount : amount;
hsl[2] = clamp( relative
? (hsl[2] * ((100 + amount2) / 100))
: (hsl[2] + amount2) );
}
protected boolean shouldInverse( float[] hsl ) {
return hsl[2] >= 50;
}
}
//---- class Darken -------------------------------------------------------
/**
* Decrease the lightness of a color in the HSL color space by an absolute
* or relative amount.
*/
public static class Darken
extends Lighten
{
public Darken( float amount, boolean relative, boolean autoInverse ) {
super( -amount, relative, autoInverse );
}
@Override
protected boolean shouldInverse( float[] hsl ) {
return hsl[2] < 50;
}
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2019 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
*
* http://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.util;
import java.awt.Color;
import javax.swing.plaf.ColorUIResource;
import com.formdev.flatlaf.util.ColorFunctions.ColorFunction;
/**
* A (red) color that acts as a placeholder in UI defaults.
* The actual color is derived from another color,
* which is modified by the given color functions.
*
* @author Karl Tauber
*/
public class DerivedColor
extends ColorUIResource
{
private final ColorFunction[] functions;
public DerivedColor( ColorFunction... functions ) {
super( Color.red );
this.functions = functions;
}
public Color derive( Color baseColor ) {
return ColorFunctions.applyFunctions( baseColor, functions );
}
}

View File

@@ -0,0 +1,432 @@
/*
* From http://tips4java.wordpress.com/2009/07/05/hsl-color/
*
* License note on http://tips4java.wordpress.com/about/
* "You are free to use and/or modify any or all code posted on the
* Java Tips Weblog without restriction. A credit in the code comments
* would be nice, but not in any way mandatory."
*/
package com.formdev.flatlaf.util;
import java.awt.Color;
/**
* The HSLColor class provides methods to manipulate HSL (Hue, Saturation
* Luminance) values to create a corresponding Color object using the RGB
* ColorSpace.
*
* The HUE is the color, the Saturation is the purity of the color (with
* respect to grey) and Luminance is the brightness of the color (with respect
* to black and white)
*
* The Hue is specified as an angel between 0 - 360 degrees where red is 0,
* green is 120 and blue is 240. In between you have the colors of the rainbow.
* Saturation is specified as a percentage between 0 - 100 where 100 is fully
* saturated and 0 approaches gray. Luminance is specified as a percentage
* between 0 - 100 where 0 is black and 100 is white.
*
* In particular the HSL color space makes it easier change the Tone or Shade
* of a color by adjusting the luminance value.
*/
public class HSLColor
{
private final Color rgb;
private final float[] hsl;
private final float alpha;
/**
* Create a HSLColor object using an RGB Color object.
*
* @param rgb the RGB Color object
*/
public HSLColor(Color rgb)
{
this.rgb = rgb;
hsl = fromRGB( rgb );
alpha = rgb.getAlpha() / 255.0f;
}
/**
* Create a HSLColor object using individual HSL values and a default
* alpha value of 1.0.
*
* @param h is the Hue value in degrees between 0 - 360
* @param s is the Saturation percentage between 0 - 100
* @param l is the Lumanance percentage between 0 - 100
*/
public HSLColor(float h, float s, float l)
{
this(h, s, l, 1.0f);
}
/**
* Create a HSLColor object using individual HSL values.
*
* @param h the Hue value in degrees between 0 - 360
* @param s the Saturation percentage between 0 - 100
* @param l the Lumanance percentage between 0 - 100
* @param alpha the alpha value between 0 - 1
*/
public HSLColor(float h, float s, float l, float alpha)
{
hsl = new float[] {h, s, l};
this.alpha = alpha;
rgb = toRGB(hsl, alpha);
}
/**
* Create a HSLColor object using an an array containing the
* individual HSL values and with a default alpha value of 1.
*
* @param hsl array containing HSL values
*/
public HSLColor(float[] hsl)
{
this(hsl, 1.0f);
}
/**
* Create a HSLColor object using an an array containing the
* individual HSL values.
*
* @param hsl array containing HSL values
* @param alpha the alpha value between 0 - 1
*/
public HSLColor(float[] hsl, float alpha)
{
this.hsl = hsl;
this.alpha = alpha;
rgb = toRGB(hsl, alpha);
}
/**
* Create a RGB Color object based on this HSLColor with a different
* Hue value. The degrees specified is an absolute value.
*
* @param degrees - the Hue value between 0 - 360
* @return the RGB Color object
*/
public Color adjustHue(float degrees)
{
return toRGB(degrees, hsl[1], hsl[2], alpha);
}
/**
* Create a RGB Color object based on this HSLColor with a different
* Luminance value. The percent specified is an absolute value.
*
* @param percent - the Luminance value between 0 - 100
* @return the RGB Color object
*/
public Color adjustLuminance(float percent)
{
return toRGB(hsl[0], hsl[1], percent, alpha);
}
/**
* Create a RGB Color object based on this HSLColor with a different
* Saturation value. The percent specified is an absolute value.
*
* @param percent - the Saturation value between 0 - 100
* @return the RGB Color object
*/
public Color adjustSaturation(float percent)
{
return toRGB(hsl[0], percent, hsl[2], alpha);
}
/**
* Create a RGB Color object based on this HSLColor with a different
* Shade. Changing the shade will return a darker color. The percent
* specified is a relative value.
*
* @param percent - the value between 0 - 100
* @return the RGB Color object
*/
public Color adjustShade(float percent)
{
float multiplier = (100.0f - percent) / 100.0f;
float l = Math.max(0.0f, hsl[2] * multiplier);
return toRGB(hsl[0], hsl[1], l, alpha);
}
/**
* Create a RGB Color object based on this HSLColor with a different
* Tone. Changing the tone will return a lighter color. The percent
* specified is a relative value.
*
* @param percent - the value between 0 - 100
* @return the RGB Color object
*/
public Color adjustTone(float percent)
{
float multiplier = (100.0f + percent) / 100.0f;
float l = Math.min(100.0f, hsl[2] * multiplier);
return toRGB(hsl[0], hsl[1], l, alpha);
}
/**
* Get the Alpha value.
*
* @return the Alpha value.
*/
public float getAlpha()
{
return alpha;
}
/**
* Create a RGB Color object that is the complementary color of this
* HSLColor. This is a convenience method. The complementary color is
* determined by adding 180 degrees to the Hue value.
* @return the RGB Color object
*/
public Color getComplementary()
{
float hue = (hsl[0] + 180.0f) % 360.0f;
return toRGB(hue, hsl[1], hsl[2]);
}
/**
* Get the Hue value.
*
* @return the Hue value.
*/
public float getHue()
{
return hsl[0];
}
/**
* Get the HSL values.
*
* @return the HSL values.
*/
public float[] getHSL()
{
return hsl;
}
/**
* Get the Luminance value.
*
* @return the Luminance value.
*/
public float getLuminance()
{
return hsl[2];
}
/**
* Get the RGB Color object represented by this HDLColor.
*
* @return the RGB Color object.
*/
public Color getRGB()
{
return rgb;
}
/**
* Get the Saturation value.
*
* @return the Saturation value.
*/
public float getSaturation()
{
return hsl[1];
}
@Override
public String toString()
{
String toString =
"HSLColor[h=" + hsl[0] +
",s=" + hsl[1] +
",l=" + hsl[2] +
",alpha=" + alpha + "]";
return toString;
}
/**
* Convert a RGB Color to it corresponding HSL values.
*
* @return an array containing the 3 HSL values.
*/
public static float[] fromRGB(Color color)
{
// Get RGB values in the range 0 - 1
float[] rgb = color.getRGBColorComponents( null );
float r = rgb[0];
float g = rgb[1];
float b = rgb[2];
// Minimum and Maximum RGB values are used in the HSL calculations
float min = Math.min(r, Math.min(g, b));
float max = Math.max(r, Math.max(g, b));
// Calculate the Hue
float h = 0;
if (max == min)
h = 0;
else if (max == r)
h = ((60 * (g - b) / (max - min)) + 360) % 360;
else if (max == g)
h = (60 * (b - r) / (max - min)) + 120;
else if (max == b)
h = (60 * (r - g) / (max - min)) + 240;
// Calculate the Luminance
float l = (max + min) / 2;
// System.out.println(max + " : " + min + " : " + l);
// Calculate the Saturation
float s = 0;
if (max == min)
s = 0;
else if (l <= .5f)
s = (max - min) / (max + min);
else
s = (max - min) / (2 - max - min);
// System.out.println(new HSLColor( new float[] {h, s * 100, l * 100} ));
return new float[] {h, s * 100, l * 100};
}
/**
* Convert HSL values to a RGB Color with a default alpha value of 1.
* H (Hue) is specified as degrees in the range 0 - 360.
* S (Saturation) is specified as a percentage in the range 1 - 100.
* L (Lumanance) is specified as a percentage in the range 1 - 100.
*
* @param hsl an array containing the 3 HSL values
*
* @returns the RGB Color object
*/
public static Color toRGB(float[] hsl)
{
return toRGB(hsl, 1.0f);
}
/**
* Convert HSL values to a RGB Color.
* H (Hue) is specified as degrees in the range 0 - 360.
* S (Saturation) is specified as a percentage in the range 1 - 100.
* L (Lumanance) is specified as a percentage in the range 1 - 100.
*
* @param hsl an array containing the 3 HSL values
* @param alpha the alpha value between 0 - 1
*
* @returns the RGB Color object
*/
public static Color toRGB(float[] hsl, float alpha)
{
return toRGB(hsl[0], hsl[1], hsl[2], alpha);
}
/**
* Convert HSL values to a RGB Color with a default alpha value of 1.
*
* @param h Hue is specified as degrees in the range 0 - 360.
* @param s Saturation is specified as a percentage in the range 1 - 100.
* @param l Lumanance is specified as a percentage in the range 1 - 100.
*
* @returns the RGB Color object
*/
public static Color toRGB(float h, float s, float l)
{
return toRGB(h, s, l, 1.0f);
}
/**
* Convert HSL values to a RGB Color.
*
* @param h Hue is specified as degrees in the range 0 - 360.
* @param s Saturation is specified as a percentage in the range 1 - 100.
* @param l Lumanance is specified as a percentage in the range 1 - 100.
* @param alpha the alpha value between 0 - 1
*
* @returns the RGB Color object
*/
public static Color toRGB(float h, float s, float l, float alpha)
{
if (s <0.0f || s > 100.0f)
{
String message = "Color parameter outside of expected range - Saturation";
throw new IllegalArgumentException( message );
}
if (l <0.0f || l > 100.0f)
{
String message = "Color parameter outside of expected range - Luminance";
throw new IllegalArgumentException( message );
}
if (alpha <0.0f || alpha > 1.0f)
{
String message = "Color parameter outside of expected range - Alpha";
throw new IllegalArgumentException( message );
}
// Formula needs all values between 0 - 1.
h = h % 360.0f;
h /= 360f;
s /= 100f;
l /= 100f;
float q = 0;
if (l < 0.5)
q = l * (1 + s);
else
q = (l + s) - (s * l);
float p = 2 * l - q;
float r = Math.max(0, HueToRGB(p, q, h + (1.0f / 3.0f)));
float g = Math.max(0, HueToRGB(p, q, h));
float b = Math.max(0, HueToRGB(p, q, h - (1.0f / 3.0f)));
r = Math.min(r, 1.0f);
g = Math.min(g, 1.0f);
b = Math.min(b, 1.0f);
return new Color(r, g, b, alpha);
}
private static float HueToRGB(float p, float q, float h)
{
if (h < 0) h += 1;
if (h > 1 ) h -= 1;
if (6 * h < 1)
{
return p + ((q - p) * 6 * h);
}
if (2 * h < 1 )
{
return q;
}
if (3 * h < 2)
{
return p + ( (q - p) * 6 * ((2.0f / 3.0f) - h) );
}
return p;
}
}

View File

@@ -31,6 +31,10 @@
@cellFocusColor=000000 @cellFocusColor=000000
@icon=adadad @icon=adadad
# Button
@buttonHoverBackground=lighten(3%,autoInverse)
@buttonPressedBackground=lighten(6%,autoInverse)
#---- globals ---- #---- globals ----
@@ -63,8 +67,8 @@ window=@background
#---- Button ---- #---- Button ----
Button.background=4c5052 Button.background=4c5052
Button.hoverBackground=525658 Button.hoverBackground=@buttonHoverBackground
Button.pressedBackground=5c6164 Button.pressedBackground=@buttonPressedBackground
Button.borderColor=5e6060 Button.borderColor=5e6060
Button.disabledBorderColor=5e6060 Button.disabledBorderColor=5e6060
@@ -73,8 +77,8 @@ Button.hoverBorderColor=@@Button.focusedBorderColor
Button.default.background=365880 Button.default.background=365880
Button.default.foreground=bbbbbb Button.default.foreground=bbbbbb
Button.default.hoverBackground=3d6185 Button.default.hoverBackground=@buttonHoverBackground
Button.default.pressedBackground=43688c Button.default.pressedBackground=@buttonPressedBackground
Button.default.borderColor=4c708c Button.default.borderColor=4c708c
Button.default.hoverBorderColor=537699 Button.default.hoverBorderColor=537699
Button.default.focusedBorderColor=537699 Button.default.focusedBorderColor=537699
@@ -95,8 +99,8 @@ CheckBox.icon.hoverBorderColor=@@CheckBox.icon.focusedBorderColor
CheckBox.icon.selectedFocusedBorderColor=466D94 CheckBox.icon.selectedFocusedBorderColor=466D94
CheckBox.icon.background=43494A CheckBox.icon.background=43494A
CheckBox.icon.disabledBackground=@background CheckBox.icon.disabledBackground=@background
CheckBox.icon.hoverBackground=4c5052 CheckBox.icon.hoverBackground=@buttonHoverBackground
CheckBox.icon.pressedBackground=@@Button.pressedBackground CheckBox.icon.pressedBackground=@buttonPressedBackground
CheckBox.icon.selectedBackground=43494A CheckBox.icon.selectedBackground=43494A
CheckBox.icon.checkmarkColor=A7A7A7 CheckBox.icon.checkmarkColor=A7A7A7
CheckBox.icon.disabledCheckmarkColor=606060 CheckBox.icon.disabledCheckmarkColor=606060

View File

@@ -31,6 +31,10 @@
@cellFocusColor=000000 @cellFocusColor=000000
@icon=afafaf @icon=afafaf
# Button
@buttonHoverBackground=darken(3%,autoInverse)
@buttonPressedBackground=darken(10%,autoInverse)
#---- globals ---- #---- globals ----
@@ -64,8 +68,8 @@ window=@background
Button.background=ffffff Button.background=ffffff
Button.focusedBackground=e3f1fa Button.focusedBackground=e3f1fa
Button.hoverBackground=f8f8f8 Button.hoverBackground=@buttonHoverBackground
Button.pressedBackground=dfdfdf Button.pressedBackground=@buttonPressedBackground
Button.borderColor=bfbfbf Button.borderColor=bfbfbf
Button.disabledBorderColor=cfcfcf Button.disabledBorderColor=cfcfcf
@@ -75,8 +79,8 @@ Button.hoverBorderColor=@@Button.focusedBorderColor
Button.default.background=@@Button.background Button.default.background=@@Button.background
Button.default.foreground=@foreground Button.default.foreground=@foreground
Button.default.focusedBackground=@@Button.focusedBackground Button.default.focusedBackground=@@Button.focusedBackground
Button.default.hoverBackground=@@Button.hoverBackground Button.default.hoverBackground=@buttonHoverBackground
Button.default.pressedBackground=@@Button.pressedBackground Button.default.pressedBackground=@buttonPressedBackground
Button.default.borderColor=4D89C9 Button.default.borderColor=4D89C9
Button.default.hoverBorderColor=@@Button.hoverBorderColor Button.default.hoverBorderColor=@@Button.hoverBorderColor
Button.default.focusedBorderColor=@@Button.focusedBorderColor Button.default.focusedBorderColor=@@Button.focusedBorderColor
@@ -97,8 +101,8 @@ CheckBox.icon.hoverBorderColor=@@CheckBox.icon.focusedBorderColor
CheckBox.icon.background=FFFFFF CheckBox.icon.background=FFFFFF
CheckBox.icon.disabledBackground=@background CheckBox.icon.disabledBackground=@background
CheckBox.icon.focusedBackground=@@Button.focusedBackground CheckBox.icon.focusedBackground=@@Button.focusedBackground
CheckBox.icon.hoverBackground=@@Button.hoverBackground CheckBox.icon.hoverBackground=@buttonHoverBackground
CheckBox.icon.pressedBackground=@@Button.pressedBackground CheckBox.icon.pressedBackground=@buttonPressedBackground
CheckBox.icon.selectedBackground=FFFFFF CheckBox.icon.selectedBackground=FFFFFF
CheckBox.icon.checkmarkColor=4D89C9 CheckBox.icon.checkmarkColor=4D89C9
CheckBox.icon.disabledCheckmarkColor=ABABAB CheckBox.icon.disabledCheckmarkColor=ABABAB