Arc.java
package swingtree.style;
import com.google.errorprone.annotations.Immutable;
import swingtree.UI;
import java.awt.*;
/**
* A value object that represents the arc width and height of a rounded rectangle corner
* as part of a component {@link StyleConf}.
*/
@Immutable
final class Arc
{
private static final Arc _NONE = new Arc(-1, -1);
/**
* Exposes the "null" object for the {@link Arc} class, which is an arc
* with width and height of -1. It is used to represent the absence of an arc,
* and instead of using null references.
*
* @return An {@link Arc} with width and height of -1.
*/
static Arc none() { return _NONE; }
/**
* A factory method for creating an {@link Arc} from the provided width and height values.
*
* @param arcWidth The width of the arc.
* @param arcHeight The height of the arc.
* @return An {@link Arc} representing the 2 values.
*/
static Arc of( float arcWidth, float arcHeight ) {
if ( arcWidth < 0 && arcHeight < 0 )
return _NONE;
return new Arc( arcWidth, arcHeight );
}
static Arc of( double arcWidth, double arcHeight ) {
return Arc.of( (float) arcWidth, (float) arcHeight );
}
private final float _arcWidth;
private final float _arcHeight;
private Arc( float arcWidth, float arcHeight ) {
_arcWidth = Math.max(-1, arcWidth);
_arcHeight = Math.max(-1, arcHeight);
}
/**
* Exposes the width of the arc, which can be thought of as the width
* of the bounding rectangle of an arc.
*
* @return The width of the arc.
*/
public float width() { return _arcWidth; }
/**
* Exposes the height of the arc, which can be thought of as the height
* of the bounding rectangle of an arc.
*
* @return The height of the arc.
*/
public float height() { return _arcHeight; }
/**
* Used to scale the arc, which is usually needed by the style engine
* to paint DPI scaled corners and also useful for when you
* need to do custom painting logic which is also supposed to be
* high DPI screen aware, see methods like
* {@link swingtree.UI#scale(int)}, {@link swingtree.UI#scale(Rectangle)}... <br>
* Also checkout {@link UI#scale()} to get the current scaling factor.
*
* @param scale A scaling factor by which the values of this arc are multiplied.
* @return A new scaled {@link Arc}.
*/
Arc scale( double scale ) {
if ( this.equals(_NONE) )
return _NONE;
return Arc.of(
(float) (_arcWidth * scale),
(float) (_arcHeight * scale)
);
}
Arc simplified() {
if ( this.equals(_NONE) )
return _NONE;
if ( _arcWidth <= 0 || _arcHeight <= 0 )
return _NONE;
return this;
}
@Override
public String toString() {
if ( this.equals(_NONE) )
return "Arc[NONE]";
return this.getClass().getSimpleName()+"[" +
"arcWidth=" + _toString(_arcWidth ) + ", "+
"arcHeight=" + _toString(_arcHeight) +
"]";
}
static String _toString( float value ) {
if ( value == -1 )
return "?";
else
return String.valueOf(value).replace(".0", "");
}
@Override
public int hashCode() {
int hash = 7;
hash = 31 * hash + Float.floatToIntBits(_arcWidth);
hash = 31 * hash + Float.floatToIntBits(_arcHeight);
return hash;
}
@Override
public boolean equals( Object obj ) {
if ( obj == null ) return false;
if ( obj == this ) return true;
if ( obj.getClass() != getClass() ) return false;
Arc other = (Arc) obj;
return _arcWidth == other._arcWidth && _arcHeight == other._arcHeight;
}
}