package nl.utwente.viskell.ui.components; import java.util.Optional; import java.util.Set; import javafx.scene.control.Label; import nl.utwente.viskell.haskell.expr.Annotated; import nl.utwente.viskell.haskell.expr.Expression; import nl.utwente.viskell.haskell.type.Type; import nl.utwente.viskell.haskell.type.TypeScope; import nl.utwente.viskell.ui.BlockContainer; /** An internal input anchor for a local result. */ public class ResultAnchor extends InputAnchor { private final WrappedContainer container; /** The optional type of the result of the function (the last part of the signature). */ private Optional<Type> resType; /** The type label of this anchor. */ private final Label typeLabel; // FIXME ResultAnchor should not have or use the DefinitionBlock parent public ResultAnchor(WrappedContainer container, Block parent, Optional<Type> resType) { super(parent); this.container = container; this.resType = resType; this.typeLabel = new Label("....."); this.typeLabel.setMinWidth(USE_PREF_SIZE); this.typeLabel.setPickOnBounds(false); this.typeLabel.setMouseTransparent(true); this.typeLabel.getStyleClass().add("resultType"); this.typeLabel.setTranslateY(9); this.getChildren().add(this.typeLabel); this.setTranslateY(-9); } @Override public Expression getLocalExpr(Set<OutputAnchor> outsideAnchors) { if (resType.isPresent()) { return new Annotated(super.getLocalExpr(outsideAnchors), resType.get()); } return super.getLocalExpr(outsideAnchors); } protected void setConstraintType(Type ctype) { this.resType = Optional.of(ctype); } /** Set fresh type for the next typechecking cycle.*/ protected void refreshAnchorType(TypeScope scope) { if (resType.isPresent()) { setFreshRequiredType(resType.get(), scope); } else { setFreshRequiredType(new TypeScope().getVar("res"), scope); } } @Override protected void handleConnectionChanges(boolean finalPhase) { container.handleConnectionChanges(finalPhase); } @Override public BlockContainer getContainer() { return this.container; } @Override public void invalidateVisualState() { super.invalidateVisualState(); boolean validConnection = this.hasValidConnection(); this.setTranslateY(validConnection ? 0 : -9); this.typeLabel.setText(validConnection ? "zyxwv" : this.getStringType()); this.typeLabel.setVisible(!validConnection); } }