Commit 0c72a307 authored by Nico Mack's avatar Nico Mack

Added radial display capabilities to Sector corona.

Improved getIntegerValue method of StringUtils class.
parent c27e4834
......@@ -128,6 +128,7 @@ PROPERTY_NODE=property
PROVIDER_NODE=provider
PROVIDERS_NODE=providers
RADIUS_NODE=radius
RADIAL_LAYOUT_NODE=radialLayout
RAMPING_TIME_NODE=rampingTime
RECEIVER_NODE=receiver
RECEIVERS_NODE=receivers
......
......@@ -90,6 +90,9 @@ public class BootstrappingUtils {
private static final String MILLIMETERS = "mm"; //$NON-NLS-1$
private static final String CAMERA = ""; //$NON-NLS-1$
private static final String POSITIVE_INFINITY = "+INF"; //$NON-NLS-1$
private static final String NEGATIVE_INFINITY = "-INF"; //$NON-NLS-1$
private static final int TWO_POWER_EIGHT = 255;
private static final String MANDATORY_NODE_TEMPLATE = "Node {} is mandatory and MUST be provided!"; //$NON-NLS-1$
......@@ -114,12 +117,42 @@ public class BootstrappingUtils {
FONT_STYLES.put(ITALIC, Font.ITALIC);
}
private static final Map<String, Double> SPECIAL_DOUBLES = new HashMap<>();
static {
SPECIAL_DOUBLES.put(NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
SPECIAL_DOUBLES.put(POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
}
private static final Map<String, Integer> SPECIAL_INTEGERS = new HashMap<>();
static {
SPECIAL_INTEGERS.put(NEGATIVE_INFINITY, -Integer.MAX_VALUE);
SPECIAL_INTEGERS.put(POSITIVE_INFINITY, Integer.MAX_VALUE);
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Primitives
// ***************************************************************************
// ---------------------------------------------------------------------------
private static Double parseDouble(String doubleString) {
if (SPECIAL_DOUBLES.containsKey(doubleString)) {
return SPECIAL_DOUBLES.get(doubleString);
}
return Double.parseDouble(doubleString);
}
// ---------------------------------------------------------------------------
private static Integer parseInteger(String integerString) {
if (SPECIAL_INTEGERS.containsKey(integerString)) {
return SPECIAL_INTEGERS.get(integerString);
}
return Integer.parseInt(integerString);
}
// ---------------------------------------------------------------------------
private static void logAndThrowBuildException(BuildException exception, Element element, String childName) throws BuildException {
Element causedBy = ((childName != null) && (childName.length() > 0)) ? element.getChild(childName) : element;
......@@ -225,7 +258,7 @@ public class BootstrappingUtils {
String unit = dimensionMatcher.group(2);
unit = (Strings.isNullOrEmpty(unit)) ? CAMERA : unit.toLowerCase(); // $NON-NLS-1$
try {
value = Double.parseDouble(dimensionAsString);
value = parseDouble(dimensionAsString);
} catch (NumberFormatException exception) {
logAndThrowBuildException(new BuildException(StringUtils.build(NON_DECIMAL_NODE_TEMPLATE, childName, contentAsString)), rootElement, childName);
}
......@@ -283,7 +316,7 @@ public class BootstrappingUtils {
String unit = angleMatcher.group(2);
unit = (Strings.isNullOrEmpty(unit)) ? targetUnit : unit.toLowerCase(); // $NON-NLS-1$
try {
value = Double.parseDouble(angle);
value = parseDouble(angle);
} catch (NumberFormatException exception) {
logAndThrowBuildException(new BuildException(StringUtils.build(NON_DECIMAL_NODE_TEMPLATE, childName, contentAsString)), rootElement, childName);
}
......@@ -457,7 +490,7 @@ public class BootstrappingUtils {
String contentAsString = Strings.nullToEmpty(getContent(rootElement, childName, variables));
if (contentAsString.length() > 0) {
try {
value = Double.parseDouble(contentAsString);
value = parseDouble(contentAsString);
} catch (NumberFormatException exception) {
logAndThrowBuildException(new BuildException(StringUtils.build(NON_DECIMAL_NODE_TEMPLATE, childName, contentAsString)), rootElement, childName);
}
......@@ -520,7 +553,7 @@ public class BootstrappingUtils {
String attributeAsString = Strings.nullToEmpty(rootElement.getAttributeValue(attributeName));
if (attributeAsString.length() > 0) {
try {
value = Double.parseDouble(attributeAsString);
value = parseDouble(attributeAsString);
} catch (NumberFormatException exception) {
logAndThrowBuildException(new BuildException(StringUtils.build(NON_DECIMAL_ATTRIBUTE_TEMPLATE, attributeName, attributeAsString)), rootElement, null);
}
......@@ -569,7 +602,7 @@ public class BootstrappingUtils {
Double doubleValue = Double.NaN;
try {
doubleValue = Double.parseDouble(contentAsString);
doubleValue = parseDouble(contentAsString);
} catch (NumberFormatException exception2) {
logAndThrowBuildException(new BuildException(StringUtils.build(NON_INTEGER_NODE_TEMPLATE, childName, contentAsString)), rootElement, childName);
}
......@@ -641,7 +674,7 @@ public class BootstrappingUtils {
String attributeAsString = Strings.nullToEmpty(rootElement.getAttributeValue(attributeName));
if (attributeAsString.length() > 0) {
try {
value = Integer.parseInt(attributeAsString);
value = parseInteger(attributeAsString);
} catch (NumberFormatException exception) {
logAndThrowBuildException(new BuildException(StringUtils.build(NON_INTEGER_ATTRIBUTE_TEMPLATE, attributeName, attributeAsString)), rootElement, null);
}
......
......@@ -163,6 +163,7 @@ public class Externalization extends NLS {
public static String PROVIDER_NODE;
public static String PROVIDERS_NODE;
public static String RADIUS_NODE;
public static String RADIAL_LAYOUT_NODE;
public static String RAMPING_TIME_NODE;
public static String RECEIVER_NODE;
public static String RECEIVERS_NODE;
......
......@@ -39,6 +39,8 @@ public class StringUtils {
private static final Pattern TITLE_CASE_PATTERN = Pattern.compile("\\b([a-z]).*?", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
private static final Pattern HEX_PATTERN = Pattern.compile("0x([0-9abcdef]+)", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
private static final Logger LOGGER = LoggerFactory.getLogger(StringUtils.class.getSimpleName());
// ---------------------------------------------------------------------------
......@@ -49,8 +51,14 @@ public class StringUtils {
public static Integer getIntegerValue(String valueAsString) {
Integer value = null;
Matcher hexMatcher = HEX_PATTERN.matcher(valueAsString);
try {
value = Integer.parseInt(valueAsString);
if (hexMatcher.matches()) {
value = Integer.parseInt(hexMatcher.group(1), 16);
} else {
value = Integer.parseInt(valueAsString);
}
} catch (NumberFormatException exception) {
LOGGER.error("Failed to convert {} to an integer value!", valueAsString); //$NON-NLS-1$
}
......
......@@ -20,6 +20,7 @@ import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
/**
......@@ -42,6 +43,7 @@ public class Sector extends SelectableCorona {
protected int startAngle;
protected int arcSpan;
protected int gap;
protected int insetBorder;
protected int strokeWidth;
protected ColorPair fillColour;
protected ColorPair strokeColour;
......@@ -52,6 +54,7 @@ public class Sector extends SelectableCorona {
protected Stroke borderStroke;
protected Font textFont;
protected boolean centered;
protected boolean radialLayout;
protected TouchManager touchManager;
......@@ -81,9 +84,12 @@ public class Sector extends SelectableCorona {
textColour = builder.textColour;
textFont = builder.textFont;
gap = builder.gap;
insetBorder = builder.insetBorder;
this.startAngle = builder.startAngle;
arcSpan = builder.arcSpan;
centered = builder.centered;
radialLayout = builder.radialLayout;
this.buildSectorFromProperties();
......@@ -111,9 +117,11 @@ public class Sector extends SelectableCorona {
textColour = original.textColour;
textFont = original.textFont;
gap = original.gap;
insetBorder = original.insetBorder;
startAngle = original.startAngle;
arcSpan = original.arcSpan;
centered = original.centered;
radialLayout = original.radialLayout;
this.buildSectorFromProperties();
......@@ -163,32 +171,48 @@ public class Sector extends SelectableCorona {
protected void renderLabel(String newLabel) {
if ((newLabel != null) && (newLabel.length() > 0)) {
boolean flipped = false;
double angle = this.getAngle();
int quadrant = AngleUtils.getQuadrant(Math.toRadians(angle));
boolean flipped = (quadrant == 2) || (quadrant == 3);
angle = (THREE_SIXTY - angle);
angle = THREE_SIXTY - angle;
FontRenderContext renderingContext = new FontRenderContext(null, true, true);
LineMetrics metrics = textFont.getLineMetrics(newLabel, renderingContext);
Shape labelPath;
if (!radialLayout) {
flipped = (quadrant == 2) || (quadrant == 3);
double labelRadius = outerRadius - metrics.getAscent() / 2;
double start = (!flipped) ? angle - arcSpan : angle;
int length = (!flipped) ? arcSpan : -arcSpan;
Rectangle2D bounds = new Rectangle2D.Double(centre.x - labelRadius,
centre.y - labelRadius,
(2 * labelRadius),
(2 * labelRadius));
double labelRadius = outerRadius - metrics.getAscent() / 2;
labelPath = new Arc2D.Double(bounds, start, length, Arc2D.OPEN);
} else {
angle = AngleUtils.moduloThreeSixty(startAngle + ((double) arcSpan / 2));
flipped = (quadrant == 1) || (quadrant == 2);
// Rectangle2D bounds = new Rectangle2D.Double(centre.x - labelRadius, centre.y - labelRadius, (2 *
// labelRadius), (2 * labelRadius));
Rectangle2D bounds = new Rectangle2D.Double(-labelRadius, -labelRadius, (2 * labelRadius), (2 * labelRadius));
double lineHeight = metrics.getAscent() / 2;
double start = (!flipped) ? angle - arcSpan : angle;
int length = (!flipped) ? arcSpan : -arcSpan;
double start = (!flipped) ? innerRadius + insetBorder : outerRadius - insetBorder;
double end = (!flipped) ? outerRadius - insetBorder : innerRadius + insetBorder;
Shape path = new Arc2D.Double(bounds, start, length, Arc2D.OPEN);
Shape centreLine = new Line2D.Double(start, lineHeight, end, lineHeight);
AffineTransform rotate = AffineTransform.getRotateInstance(Math.toRadians(angle));
labelPath = rotate.createTransformedShape(centreLine);
}
TextStroke stroke = new TextStroke(newLabel, textFont, false, centered, false);
stroke.setFlipped(flipped);
curvedText = stroke.createStrokedShape(path);
curvedText = stroke.createStrokedShape(labelPath);
this.label = newLabel;
}
}
......
......@@ -50,6 +50,9 @@ public abstract class BaseSectorBuilder<B extends BaseSectorBuilder<B>> extends
public int arcSpan;
/** Specifies an optional gap (spacer) on both ends of the sector to build */
public int gap;
public int insetBorder;
/** Specifies the color pair (selected / unselected) to be used for filling the sector */
public ColorPair fillColour;
/**
......@@ -67,6 +70,7 @@ public abstract class BaseSectorBuilder<B extends BaseSectorBuilder<B>> extends
public Font textFont;
/** */
public boolean centered;
public boolean radialLayout;
// ***************************************************************************
// * Constants *
......@@ -128,6 +132,7 @@ public abstract class BaseSectorBuilder<B extends BaseSectorBuilder<B>> extends
gap = (int) BootstrappingUtils.getContentAsDegrees(rootElement, Externalization.GAP_NODE, BootstrappingUtils.OPTIONAL, 0d, context);
strokeWidth = BootstrappingUtils.getContentAsInteger(rootElement, Externalization.STROKE_WIDTH_NODE, BootstrappingUtils.OPTIONAL, 1, context);
insetBorder = BootstrappingUtils.getContentAsInteger(rootElement, Externalization.INSET_BORDER_NODE, BootstrappingUtils.OPTIONAL, 0, context);
fillColour = buildColorPair(rootElement.getChild(Externalization.FILL_COLOUR_ELEMENT), context);
textColour = buildColorPair(rootElement.getChild(Externalization.TEXT_COLOUR_ELEMENT), context);
......@@ -138,6 +143,8 @@ public abstract class BaseSectorBuilder<B extends BaseSectorBuilder<B>> extends
String fontName = BootstrappingUtils.getContentAsString(rootElement, Externalization.FONT_NODE, BootstrappingUtils.OPTIONAL, "Monospaced", context); //$NON-NLS-1$
Integer fontSize = BootstrappingUtils.getContentAsInteger(rootElement, Externalization.FONT_SIZE_NODE, BootstrappingUtils.OPTIONAL, 14, context);
centered = BootstrappingUtils.getContentAsBoolean(rootElement, Externalization.CENTRED_NODE, BootstrappingUtils.OPTIONAL, Boolean.TRUE, context);
radialLayout = BootstrappingUtils.getContentAsBoolean(rootElement, Externalization.RADIAL_LAYOUT_NODE, BootstrappingUtils.OPTIONAL, Boolean.FALSE, context);
if ((fontName != null) && (fontName.length() > 0)) {
textFont = new Font(fontName, Font.BOLD, fontSize);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment