package ui.renderer;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JComponent;
import common.Environment;
import expressions.Expression;
/**
* Compoment containing the expression aswell as an environment.
* <br>
* It is checked wether the environment should be rendered or if
* it should be checked for the sizecalculation.
*
* @author marcell
*
* @param <S> Symbol: Location for Big/SmallStep Identifier for Typechecker
* @param <E> Entry: Expression for Big/SmallStep Store for the Typechecker
*/
public class CompoundExpression<S, E> extends JComponent{
/**
* The environment assigned to this expression.
*/
private Environment<S, E> environment = null;
/**
* Renderer that will be used to render the environment
* and to determin the needed size for it.
*/
private EnvironmentRenderer<S, E> environmentRenderer = null;
/**
* Calculated size for the environment.
*/
private Dimension environmentDimension = null;
/**
* The expression itself.
*/
private Expression expression = null;
/**
* Renderer that will be used to render the expression
* and to determin the possible sizes for the expression.
*/
private ExpressionRenderer expressionRenderer = null;
/**
* Calculated size for the expression.
*/
private Dimension expressionDimension = null;
/**
* Expression that will be underlined. Only used in BigStep
*/
private Expression underlineExpression = null;
/**
* Width for the parenthesis around the compound of expression and
* environment in pixels. When no environment is set this variable is ignored.
*/
private int parenthesisWidth = 10;
/**
* Spacing between the expression and the environment in pixels.
* When no environment is set this variable is ignored.
*/
private int spacing = 10;
/**
* Whether the expression/environment should be rendered using the
* colors given by the active Theme or just in a light gray.
*
* When this CompountExpression is used as the result expression in
* the BigStep this should be FALSE else TRUE.
*/
private boolean useColoring = true;
/**
* Default constructor initiates the expression aswell as the environment
* with null.
*
*/
public CompoundExpression () {
}
/**
* Initiates the expression with the given one. The environment will be
* set to null. setExpression will get called.
*
* @param expression The expression that should be assigned to this CompoundExpression.
*/
public CompoundExpression (Expression expression) {
setExpression (expression);
}
/**
* Initiates the expression and the environment with the given values.
* setExpression and setEnvironment will get called.
*
* @param expression The expression that should be assigned to this CompoundExpression.
* @param environment The environment that should be assigned to this CompoundExpression.
*/
public CompoundExpression (Expression expression, Environment<S, E> environment) {
setExpression (expression);
setEnvironment (environment);
}
/**
* Sets whether the expression and the environment should be rendered using the
* colors from the active theme or just get rendered in a light gray.
*
* When using this CompoundExpression as a return value of the BigStep this should
* be set FALSE else TRUE.
*
* @param coloring TRUE when colors should be used else FALSE.
*/
public void setUseColoring (boolean coloring) {
this.useColoring = coloring;
}
/**
* Assigns a new expression to the CompoundExpression. The possible line wraps
* are tested directly aswell as the propper Renderer is created for it.
*
* @param expression The expression that should be assigned to this CompoundExpression.
*/
public void setExpression (Expression expression) {
this.expression = expression;
if (this.expression != null) {
this.expressionRenderer = new ExpressionRenderer (this.expression);
this.expressionRenderer.checkFonts();
this.expressionRenderer.checkAnnotationSizes();
}
else {
this.expressionRenderer = null;
}
}
/**
* Sets the Expression that should get underlined during rendering.
*
* This is only importend for the SmallStep.
*
* @param underlineExpression
*/
public void setUnderlineExpression (Expression underlineExpression) {
this.underlineExpression = underlineExpression;
}
/**
* Assigns a new environment to the CompoundExpression. The renderer that
* will be used to render the environment is created aswell.
*
* @param environment
*/
public void setEnvironment (Environment<S, E> environment) {
this.environment = environment;
if (this.environment != null) {
this.environmentRenderer = new EnvironmentRenderer<S, E>(this.environment);
this.environmentRenderer.checkFonts();
}
else {
this.environmentRenderer = null;
}
}
/**
* Calculates the Dimension this Component needs to show all its content
* in respect to the width available.
* <br>
* WARNING! The returned Dimension may be wider then the given width.
*
* @param width The visible width of the parent view.
* @return
*/
public Dimension getDimensions (int width) {
this.environmentDimension = null;
this.expressionDimension = null;
int extendedWidth = 0;
if (this.environment == null && this.expression == null) {
return new Dimension (0, 0);
}
if (this.environment != null) {
extendedWidth = 2 * this.parenthesisWidth + this.spacing;
width -= extendedWidth;
this.environmentDimension = this.environmentRenderer.getNeededSize();
}
else {
this.environmentDimension = new Dimension (0, 0);
}
this.expressionDimension = this.expressionRenderer.getNeededSize(width);
return new Dimension (expressionDimension.width + extendedWidth + environmentDimension.width, expressionDimension.height);
}
/**
* Returns the maximum width the expression (without the environment) needs
* when no line wrapping is enabled.
*
* @return
*/
public Dimension getMaxExpressionDimension () {
if (this.expression == null) {
return new Dimension (0, 0);
}
return this.expressionRenderer.getMaxSize();
}
/**
* Paints the compoment. When an environment is given parenthesis will
* get rendered around the expression and the environment.
*
* @param gc
*/
@Override
protected void paintComponent (Graphics gc) {
gc.setColor(Color.WHITE);
gc.fillRect(0, 0, getWidth () - 1, getHeight () - 1);
if (this.expression == null) {
return;
}
int posX = 0;
int posY = 0;
if (this.environment != null) {
// need space for the parenthesises
posX += this.parenthesisWidth;
}
this.expressionRenderer.setAlternativeColor(this.useColoring ? null : Color.LIGHT_GRAY);
this.expressionRenderer.render(posX, posY, this.underlineExpression, gc);
posX += this.expressionDimension.width;
if (this.environment != null) {
// there will be a comma later or something like this.
posX += this.spacing;
// render the environment here
this.environmentRenderer.setAlternativeColor(this.useColoring ? null : Color.LIGHT_GRAY);
this.environmentRenderer.render(posX, posY, getHeight (), gc);
}
}
}