package bluej.stride.framedjava.slots;

import java.util.stream.Stream;

import javafx.beans.binding.When;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import bluej.stride.generic.Frame.View;
import bluej.stride.generic.InteractionManager;
import bluej.utility.javafx.HangingFlowPane;
import bluej.utility.javafx.JavaFXUtil;
import bluej.utility.javafx.SharedTransition;


| An operator is a read-only operator label (e.g. +, *, >>, etc) in an | expression slot. | class Operator {
| The label showing the operator | private final Label l;
| The operator in the Stride source. | The Label can show different to sourceProperty, when we are doing Java preview. | private final StringProperty sourceProperty = new SimpleStringProperty();
| Keeps track of whether we are in Java preview | private final BooleanProperty showingJava = new SimpleBooleanProperty();
| The text to show for range operator when we are in Java preview mode. | For most ranges, this is a comma (since the range becomes a method call) | to separate the beginning and end. But in a for-each loop condition, | this can be more complex as it gets turned into part of a Java classic for loop. | private final StringProperty rangeJavaPreview = new SimpleStringProperty(", ");
| The precedence category of the operator. This is determined relative | to other operators around it in the same expression level, not solely | by the operator itself. | private Precedence precedence; public Operator(String op, InfixStructured parent) { sourceProperty.set(op); l = new Label(); JavaFXUtil.addStyleClass(l, "expression-operator"); l.setOnMousePressed(e -> { parent.moveTo(e.getSceneX(), e.getSceneY(), true); e.consume(); }); l.setOnMouseDragged(e -> { parent.selectTo(e.getSceneX(), e.getSceneY()); e.consume(); }); l.setOnMouseReleased(e -> { parent.selected(); e.consume(); }); l.setOnMouseMoved(e -> { if (e.isShortcutDown()) parent.getSlot().getOverlay().hoverAtPos(-1); }); l.setOnMouseClicked(MouseEvent::consume); l.setOnDragDetected(MouseEvent::consume); l.textProperty().bind( new When(showingJava) .then(new When(sourceProperty.isEqualTo("<:")).then(" instanceof ") .otherwise(new When(sourceProperty.isEqualTo("..")).then(rangeJavaPreview) .otherwise(sourceProperty))) .otherwise(sourceProperty)); JavaFXUtil.addChangeListener(sourceProperty, s -> updateBreaks()); updateBreaks(); } private void updateBreaks() { HangingFlowPane.setBreakBefore(l, !sourceProperty.get().equals(",")); }
| Gets the precedence for the given operator. | @param op Operator to determine precedence for | @param unary Whether this operator is acting as unary (true) or binary (false) | @return An integer precedence, higher value binds tighter. | p.public static int getOperatorPrecedence(String op, boolean unary) { int prec; switch (op) { case ",": prec = 0; break; case "..": prec = 1; break; case "||": prec = 1; break; case "&&": prec = 2; break; case "|": prec = 3; break; case "^": prec = 4; break; case "&": prec = 5; break; case "=": case "==": case "!=": prec = 6; break; case "<": case ">": case ">=": case "<=": case "<:" /*instanceof prec = 7; break; case "<<": case ">>": case ">>>": prec = 8; break; case "+": case "-": prec = unary ? 11 : 9; break; case "*": case "/": case "%": prec = 10; break; case "~": case "!": prec = 12; break; case "new ": prec = 14; break; case ":": case "::": prec = 15; break; case ".": prec = 16; break; case "->": prec = 17; break; default: throw new IllegalStateException("Unknown operator: " + op); } return prec; }
| Given a numeric index of precedence group, returns a corresponding Precedence | category. | @param ourLevel Numeric index of precedence group. Highest precedence | operator in the expression gets 0 (all get 0 if joint between | several operators), next highest group gets 1, then 2, etc. | @return | p.public static Precedence getPrecForLevel(int ourLevel) { if (ourLevel == 0) { return Precedence.HIGH; } else if (ourLevel == 1) { return Precedence.MEDIUM; } else { return Precedence.LOW; } } public String getCopyText() { return sourceProperty.get(); } public Node getNode() { return l; }
| Gets the source text of the operator | public String get() { return sourceProperty.get(); }
| Sets the source text of the operator | public void set(String s) { sourceProperty.set(s); } public Precedence getPrecedence() { return precedence; }
| Sets the operator precedence and updates visual state accordingly | public void setPrecedence(Precedence chosen) { for (Precedence p : Precedence.values()) JavaFXUtil.setPseudoclass(p.getPseudoClass(), false, l); JavaFXUtil.setPseudoclass(chosen.getPseudoClass(), true, l); this.precedence = chosen; } public Stream getStartEndPositions(InfixStructured parent) { return Stream.of(TextOverlayPosition.nodeToOverlay(l, 0.0, 0.0, l.getBaselineOffset(), l.getHeight()), TextOverlayPosition.nodeToOverlay(l, l.getWidth(), 0.0, l.getBaselineOffset(), l.getHeight())); } public String getJavaCode() { if ("<:".equals(get())) return " instanceof "; else{ if (get().equals(",")) return ", "; } else if (get().equals(".")) return "."; else{ return " " + get() + " "; } } public void setView(View view, SharedTransition animate) { if (view != View.JAVA_PREVIEW) rangeJavaPreview.set(", "); showingJava.set(view == View.JAVA_PREVIEW); JavaFXUtil.setPseudoclass("bj-java-preview", view == View.JAVA_PREVIEW, l); } public void setJavaPreviewRangeOverride(String s) { rangeJavaPreview.set(s); } public Node makeDisplayClone(InteractionManager editor) { return JavaFXUtil.cloneLabel(l, editor.getFontCSS()); } public static enum Precedence { DOT, HIGH, MEDIUM, LOW, NEW, COMMA; public String getPseudoClass() { switch (this) { case DOT: return "bj-op-dot"; case HIGH: return "bj-op-high"; case MEDIUM: return "bj-op-medium"; case LOW: return "bj-op-low"; case NEW: return "bj-op-new"; case COMMA: return "bj-op-comma"; default: return null; } } } }

.   - Operator
.   Operator
.   updateBreaks
.   getOperatorPrecedence
.   getPrecForLevel
.   getCopyText
.   getNode
.   get
.   set
.   getPrecedence
.   setPrecedence
.   getStartEndPositions
.   getJavaCode
.   setView
.   setJavaPreviewRangeOverride
.   makeDisplayClone
.   getPseudoClass




293 neLoCode + 27 LoComm