Commit 11a8ff5e authored by Nico Mack's avatar Nico Mack

Implement IrisWipe corona.

Fixed API issue with ShapeGraphBuilder class
parent f1ed4f1d
/**
* Copyright Luxembourg Institute of Science and Technology, 2017. All rights reserved. If you wish
* to use this code for any purpose, please contact the author(s).
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package lu.list.itis.dkd.tui.widget.corona;
import lu.list.itis.dkd.tui.utility.ColorPair;
import lu.list.itis.dkd.tui.utility.ScreenCoordinates;
import lu.list.itis.dkd.tui.widget.corona.builder.BaseIrisWipeBuilder;
import org.pushingpixels.trident.Timeline;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
/**
* Corona used to imitate a wipe, i.e a type of film transition where one shot replaces another by
* travelling from one side of the frame to another or with a special shape.
*
* @author Nico Mack [nico.mack@list.lu]
* @since 2.7.0
* @version 1.0.0
*/
// ***************************************************************************
// * Class Definition and Members *
// ***************************************************************************
public class IrisWipe extends ValueCorona {
/** The minimum value to be stored by the widget. */
protected double lowerBound;
/** The maximum value to be stored by the widget. */
protected double upperBound;
/** The lower bound of the angle the widget can be turned to. */
protected ColorPair fillColour;
protected ColorPair strokeColour;
protected int strokeWidth;
protected Area iris;
protected int rampingTime;
protected Timeline balisticTimeline;
private double shownValue;
private Stroke borderStroke;
// ***************************************************************************
// * Constant(s) *
// ***************************************************************************
private static final Area SCREEN_MASK = new Area(new Rectangle2D.Double(
ScreenCoordinates.FULL_SCREEN.x1,
ScreenCoordinates.FULL_SCREEN.y1,
ScreenCoordinates.FULL_SCREEN.x2,
ScreenCoordinates.FULL_SCREEN.y2));
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s) *
// ***************************************************************************
// ---------------------------------------------------------------------------
/**
* @param builder
*/
public IrisWipe(BaseIrisWipeBuilder<?> builder) {
super(builder);
this.lowerBound = builder.lowerBound;
this.upperBound = builder.upperBound;
this.rampingTime = builder.rampingTime;
this.fillColour = builder.fillColour;
this.strokeColour = builder.strokeColour;
this.strokeWidth = builder.strokeWidth;
this.shape = builder.graphShape;
this.setupFromProperties();
}
// ---------------------------------------------------------------------------
/**
* Copy constructor to clone corona.
*
* @param original
* specifies the original corona to create an exact copy from.
*/
// ---------------------------------------------------------------------------
public IrisWipe(IrisWipe original) {
super(original);
this.lowerBound = original.lowerBound;
this.upperBound = original.upperBound;
this.rampingTime = original.rampingTime;
this.fillColour = original.fillColour;
this.strokeColour = original.strokeColour;
this.strokeWidth = original.strokeWidth;
this.shape = original.shape;
this.setupFromProperties();
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Primitives *
// ***************************************************************************
// ---------------------------------------------------------------------------
private void setupFromProperties() {
borderStroke = (this.strokeWidth > 0) ? new BasicStroke(this.strokeWidth) : null;
this.setShownValue(this.variable.getValue());
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body *
// ***************************************************************************
// ---------------------------------------------------------------------------
@Override
public void setSelected(boolean selectIt) {
super.setSelected(selectIt);
if (fillColour != null)
fillColour.setSwitched(selectIt);
if (strokeColour != null)
strokeColour.setSwitched(selectIt);
}
// ---------------------------------------------------------------------------
public void setShownValue(double value) {
shownValue = value;
if (variable != null) {
double size = lowerBound + ((upperBound - lowerBound) * this.variable.getNormalizedValueOf(value));
double scale = size / lowerBound;
AffineTransform scaler = AffineTransform.getScaleInstance(scale, scale);
Shape scaledShape = scaler.createTransformedShape(this.shape);
iris = new Area(new GeneralPath(scaledShape));
}
}
// ---------------------------------------------------------------------------
@Override
public Shape getShape() {
return this.iris;
}
// ---------------------------------------------------------------------------
@Override
public void paint(Graphics2D canvas) {
if (!active)
return;
Graphics2D localCanvas = (Graphics2D) canvas.create();
AffineTransform transform = this.getTransform(null);
if (this.opacity < 1.0f)
localCanvas.setComposite(AlphaComposite.SrcOver.derive(this.opacity));
if (iris != null) {
Area mask = (Area) SCREEN_MASK.clone();
Shape wipe = transform.createTransformedShape(this.iris);
mask.subtract(new Area(new GeneralPath(wipe)));
if (fillColour != null) {
localCanvas.setPaint(fillColour.getColor());
localCanvas.fill(mask);
}
if (strokeColour != null) {
localCanvas.setPaint(strokeColour.getColor());
if (borderStroke != null) {
localCanvas.setStroke(borderStroke);
localCanvas.draw(mask);
}
}
}
if (this.opacity < 1.0f)
localCanvas.setComposite(AlphaComposite.SrcOver.derive(1.0f));
localCanvas.dispose();
}
// ---------------------------------------------------------------------------
@Override
public void setInformation(Object information) {
if (variable != null) {
double value = this.variable.getValue();
if (rampingTime > 0) {
if ((balisticTimeline != null) && (!balisticTimeline.isDone()))
balisticTimeline.cancel();
balisticTimeline = new Timeline(this);
balisticTimeline.addPropertyToInterpolate("shownValue", shownValue, value); //$NON-NLS-1$
balisticTimeline.setDuration(rampingTime);
balisticTimeline.play();
} else {
this.setShownValue(value);
}
}
}
// ---------------------------------------------------------------------------
@Override
public IrisWipe clone() {
return new IrisWipe(this);
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * End of Class *
// ***************************************************************************
// ---------------------------------------------------------------------------
}
......@@ -14,7 +14,7 @@
package lu.list.itis.dkd.tui.widget.corona;
import lu.list.itis.dkd.tui.utility.ColorPair;
import lu.list.itis.dkd.tui.widget.corona.builder.ShapeGraphBuilder;
import lu.list.itis.dkd.tui.widget.corona.builder.BaseShapeGraphBuilder;
import org.pushingpixels.trident.Timeline;
import org.pushingpixels.trident.Timeline.RepeatBehavior;
......@@ -62,7 +62,7 @@ public class ShapeGraph extends ValueCorona {
/**
* @param builder
*/
public ShapeGraph(ShapeGraphBuilder builder) {
public ShapeGraph(BaseShapeGraphBuilder<?> builder) {
super(builder);
this.lowerBound = builder.lowerBound;
this.upperBound = builder.upperBound;
......
package lu.list.itis.dkd.tui.widget.corona.builder;
import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.bootstrapping.BootstrapCallback;
import lu.list.itis.dkd.tui.bootstrapping.BootstrapContext;
import lu.list.itis.dkd.tui.bootstrapping.BootstrappingUtils;
import lu.list.itis.dkd.tui.bootstrapping.ShapeBootstrapper;
import lu.list.itis.dkd.tui.exception.BuildException;
import lu.list.itis.dkd.tui.utility.ColorPair;
import lu.list.itis.dkd.tui.utility.Externalization;
import lu.list.itis.dkd.tui.utility.Point;
import lu.list.itis.dkd.tui.widget.corona.IrisWipe;
import org.jdom2.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.Color;
import java.awt.Shape;
/**
* @author nmack
* @date 08 Jan 2016
*
* <br>
* $Log: ArcGraphBuilder.java,v $
*/
// ***************************************************************************
// * Class Definition and Members *
// ***************************************************************************
public class BaseIrisWipeBuilder<B extends BaseIrisWipeBuilder<B>> extends BaseValueCoronaBuilder<B> {
public double lowerBound;
public double upperBound;
public ColorPair fillColour;
public ColorPair strokeColour;
public int strokeWidth;
public Shape graphShape;
public int rampingTime;
// ***************************************************************************
// * Constants *
// ***************************************************************************
private static Logger LOGGER = LoggerFactory.getLogger(BaseIrisWipeBuilder.class.getSimpleName());
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s) *
// ***************************************************************************
// ---------------------------------------------------------------------------
public BaseIrisWipeBuilder(Point centre) {
super(centre);
}
/**
* @param rootElement
* @throws BuildException
*/
public BaseIrisWipeBuilder(Element rootElement) throws BuildException {
super(rootElement);
this.buildFromBootstrap(rootElement, null, null);
/** Mandatory fields */
}
/**
* @param rootElement
* @throws BuildException
*/
public BaseIrisWipeBuilder(Element rootElement, BootstrapContext context, BootstrapCallback callback) throws BuildException {
super(rootElement, context, callback);
this.buildFromBootstrap(rootElement, context, callback);/** Mandatory fields */
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Primitives *
// ***************************************************************************
// ---------------------------------------------------------------------------
private void buildFromBootstrap(@Nullable Element rootElement, BootstrapContext context, BootstrapCallback callback) throws BuildException {
lowerBound = BootstrappingUtils.getContentAsDouble(rootElement, Externalization.LOWER_BOUND_NODE, BootstrappingUtils.MANDATORY, null, context);
upperBound = BootstrappingUtils.getContentAsDouble(rootElement, Externalization.UPPER_BOUND_NODE, BootstrappingUtils.MANDATORY, null, context);
/** Optional fields */
rampingTime = BootstrappingUtils.getContentAsInteger(rootElement, Externalization.RAMPING_TIME_NODE, BootstrappingUtils.OPTIONAL, 500, context);
strokeWidth = BootstrappingUtils.getContentAsInteger(rootElement, Externalization.STROKE_WIDTH_NODE, BootstrappingUtils.OPTIONAL, 1, context);
fillColour = buildColorPair(rootElement.getChild(Externalization.FILL_COLOUR_ELEMENT), context);
strokeColour = buildColorPair(rootElement.getChild(Externalization.STROKE_COLOUR_ELEMENT), context);
graphShape = ShapeBootstrapper.getShape(rootElement.getChild(Externalization.SHAPE_NODE), context, callback);
}
// ---------------------------------------------------------------------------
private ColorPair buildColorPair(Element rootElement, BootstrapContext context) throws BuildException {
Color selectedColour = BootstrappingUtils.getContentAsColour(rootElement, Externalization.SELECTED_ELEMENT, BootstrappingUtils.MANDATORY, null, context);
Color deselectedColour = BootstrappingUtils.getContentAsColour(rootElement, Externalization.DESELECTED_ELEMENT, BootstrappingUtils.MANDATORY, null, context);
return new ColorPair(selectedColour, deselectedColour);
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body *
// ***************************************************************************
// ---------------------------------------------------------------------------
@Override
public IrisWipe build() throws BuildException {
return new IrisWipe(this);
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * End of Class *
// ***************************************************************************
// ---------------------------------------------------------------------------
}
\ No newline at end of file
package lu.list.itis.dkd.tui.widget.corona.builder;
import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.bootstrapping.BootstrapCallback;
import lu.list.itis.dkd.tui.bootstrapping.BootstrapContext;
import lu.list.itis.dkd.tui.bootstrapping.BootstrappingUtils;
import lu.list.itis.dkd.tui.bootstrapping.ShapeBootstrapper;
import lu.list.itis.dkd.tui.exception.BuildException;
import lu.list.itis.dkd.tui.utility.ColorPair;
import lu.list.itis.dkd.tui.utility.CpsNamespace;
import lu.list.itis.dkd.tui.utility.Externalization;
import lu.list.itis.dkd.tui.utility.Point;
import lu.list.itis.dkd.tui.widget.corona.ShapeGraph;
import org.jdom2.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.Color;
import java.awt.Shape;
/**
* @author nmack
* @date 08 Jan 2016
*
* <br>
* $Log: ArcGraphBuilder.java,v $
*/
// ***************************************************************************
// * Class Definition and Members *
// ***************************************************************************
public class BaseShapeGraphBuilder<B extends BaseShapeGraphBuilder<B>> extends BaseValueCoronaBuilder<B> {
public double lowerBound;
public double upperBound;
public ColorPair fillColour;
public ColorPair strokeColour;
public int strokeWidth;
public Shape graphShape;
public boolean blinkOnOutOfRange;
public int rampingTime;
// ***************************************************************************
// * Constants *
// ***************************************************************************
private static Logger LOGGER = LoggerFactory.getLogger(BaseShapeGraphBuilder.class.getSimpleName());
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s) *
// ***************************************************************************
// ---------------------------------------------------------------------------
public BaseShapeGraphBuilder(Point centre) {
super(centre);
}
/**
* @param rootElement
* @throws BuildException
*/
public BaseShapeGraphBuilder(Element rootElement) throws BuildException {
super(rootElement);
this.buildFromBootstrap(rootElement, null, null);
/** Mandatory fields */
}
/**
* @param rootElement
* @throws BuildException
*/
public BaseShapeGraphBuilder(Element rootElement, BootstrapContext context, BootstrapCallback callback) throws BuildException {
super(rootElement, context, callback);
this.buildFromBootstrap(rootElement, context, callback);/** Mandatory fields */
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Primitives *
// ***************************************************************************
// ---------------------------------------------------------------------------
private void buildFromBootstrap(@Nullable Element rootElement, BootstrapContext context, BootstrapCallback callback) throws BuildException {
lowerBound = BootstrappingUtils.getContentAsDouble(rootElement, Externalization.LOWER_BOUND_NODE, BootstrappingUtils.MANDATORY, null, context);
upperBound = BootstrappingUtils.getContentAsDouble(rootElement, Externalization.UPPER_BOUND_NODE, BootstrappingUtils.MANDATORY, null, context);
/** Optional fields */
blinkOnOutOfRange = BootstrappingUtils.getContentAsBoolean(rootElement, CpsNamespace.BLINK_ON_OUT_OF_RANGE_NODE, BootstrappingUtils.OPTIONAL, Boolean.FALSE, context);
rampingTime = BootstrappingUtils.getContentAsInteger(rootElement, Externalization.RAMPING_TIME_NODE, BootstrappingUtils.OPTIONAL, 500, context);
strokeWidth = BootstrappingUtils.getContentAsInteger(rootElement, Externalization.STROKE_WIDTH_NODE, BootstrappingUtils.OPTIONAL, 1, context);
fillColour = buildColorPair(rootElement.getChild(Externalization.FILL_COLOUR_ELEMENT), context);
strokeColour = buildColorPair(rootElement.getChild(Externalization.STROKE_COLOUR_ELEMENT), context);
graphShape = ShapeBootstrapper.getShape(rootElement.getChild(Externalization.SHAPE_NODE), context, callback);
}
// ---------------------------------------------------------------------------
private ColorPair buildColorPair(Element rootElement, BootstrapContext context) throws BuildException {
Color selectedColour = BootstrappingUtils.getContentAsColour(rootElement, Externalization.SELECTED_ELEMENT, BootstrappingUtils.MANDATORY, null, context);
Color deselectedColour = BootstrappingUtils.getContentAsColour(rootElement, Externalization.DESELECTED_ELEMENT, BootstrappingUtils.MANDATORY, null, context);
return new ColorPair(selectedColour, deselectedColour);
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body *
// ***************************************************************************
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
public BaseShapeGraphBuilder withFillColours(Color selectedColour, Color deselectedColour) {
fillColour = new ColorPair(selectedColour, deselectedColour);
return this;
}
// ---------------------------------------------------------------------------
public BaseShapeGraphBuilder withStrokeColours(Color selectedColour, Color deselectedColour) {
strokeColour = new ColorPair(selectedColour, deselectedColour);
return this;
}
// ---------------------------------------------------------------------------
public BaseShapeGraphBuilder withStrokeWidth(int width) {
this.strokeWidth = width;
return this;
}
// ---------------------------------------------------------------------------
public BaseShapeGraphBuilder withGraphShape(Shape shape) {
graphShape = shape;
return this;
}
// // ---------------------------------------------------------------------------
//
// public ShapeGraphBuilder withGraphImage(SVGIcon image) {
// graphImage = image;
// return this;
// }
//
// ---------------------------------------------------------------------------
@Override
public ShapeGraph build() throws BuildException {
return new ShapeGraph(this);
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * End of Class *
// ***************************************************************************
// ---------------------------------------------------------------------------
}
\ No newline at end of file
package lu.list.itis.dkd.tui.widget.corona.builder;
import lu.list.itis.dkd.tui.bootstrapping.BootstrapCallback;
import lu.list.itis.dkd.tui.bootstrapping.BootstrapContext;
import lu.list.itis.dkd.tui.exception.BuildException;
import lu.list.itis.dkd.tui.utility.Point;
import lu.list.itis.dkd.tui.widget.corona.IrisWipe;
import org.jdom2.Element;
/**
* @author nmack
* @date 20 Jan 2016
*
* <br>
* $Log: DisplayCoronaBuilder.java,v $
*/
// ***************************************************************************
// * Class Definition and Members *
// ***************************************************************************
public class IrisWipeBuilder<B extends IrisWipeBuilder<B>> extends BaseIrisWipeBuilder<B> {
// ***************************************************************************
// * Constants *
// ***************************************************************************
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s) *
// ***************************************************************************
// ---------------------------------------------------------------------------
public IrisWipeBuilder(Point centre) {
super(centre);
}
// ---------------------------------------------------------------------------
public IrisWipeBuilder(Element rootElement) throws BuildException {
super(rootElement);
}
// ---------------------------------------------------------------------------
public IrisWipeBuilder(Element rootElement, BootstrapContext context, BootstrapCallback callback) throws BuildException {
super(rootElement, context, callback);
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Primitives *
// ***************************************************************************
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body *
// ***************************************************************************
// ---------------------------------------------------------------------------
@Override
public IrisWipe build() throws BuildException {
return new IrisWipe(this);
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * End of Class *
// ***************************************************************************
// ---------------------------------------------------------------------------
}
\ No newline at end of file
package lu.list.itis.dkd.tui.widget.corona.builder;
import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.bootstrapping.BootstrapCallback;
import lu.list.itis.dkd.tui.bootstrapping.BootstrapContext;
import lu.list.itis.dkd.tui.bootstrapping.BootstrappingUtils;
import lu.list.itis.dkd.tui.bootstrapping.ShapeBootstrapper;
import lu.list.itis.dkd.tui.exception.BuildException;
import lu.list.itis.dkd.tui.utility.ColorPair;
import lu.list.itis.dkd.tui.utility.CpsNamespace;
import lu.list.itis.dkd.tui.utility.Externalization;
import lu.list.itis.dkd.tui.utility.Point;
import lu.list.itis.dkd.tui.widget.corona.ShapeGraph;
import org.jdom2.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.Color;
import java.awt.Shape;
/**
* @author nmack
* @date 08 Jan 2016
* @date 20 Jan 2016
*
* <br>
* $Log: ArcGraphBuilder.java,v $
* $Log: DisplayCoronaBuilder.java,v $
*/
// ***************************************************************************
// * Class Definition and Members *
// ***************************************************************************
public class ShapeGraphBuilder extends ValueCoronaBuilder<ShapeGraphBuilder> {
public double lowerBound;
public double upperBound;
public ColorPair fillColour;
public ColorPair strokeColour;
public int strokeWidth;
public Shape graphShape;
public boolean blinkOnOutOfRange;
public int rampingTime;
public class ShapeGraphBuilder<B extends ShapeGraphBuilder<B>> extends BaseShapeGraphBuilder<B> {
// ***************************************************************************
// * Constants *
// ***************************************************************************
private static Logger LOGGER = LoggerFactory.getLogger(ShapeGraphBuilder.class.getSimpleName());
// ---------------------------------------------------------------------------
// *****************************************