package bluej.stride.slots;

import java.util.List;

import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.css.CssMetaData;
import javafx.css.SimpleStyleableObjectProperty;
import javafx.css.Styleable;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.util.Duration;

import bluej.stride.generic.Frame;
import bluej.stride.generic.InteractionManager;
import bluej.utility.javafx.FXConsumer;
import bluej.utility.javafx.JavaFXUtil;
import bluej.utility.javafx.SharedTransition;
import threadchecker.OnThread;
import threadchecker.Tag;


| A class for rotatable triangle to be used with hideable canvases. | In the default JavaFX font, the right-pointing triangle is much smaller than | the downward-pointing triangle, so we can't use the two triangles to toggle | the selection. Instead, we always use the downward pointing one, but rotate it. | | @author NCCB | public class TriangleLabel extends HBox implements HeaderItem{ private final SimpleBooleanProperty expanded; private final Canvas canvas = new Canvas(8, 10); private final SimpleStyleableObjectProperty<Color> cssColorProperty = new SimpleStyleableObjectProperty<>(COLOR_META_DATA); public final SimpleStyleableObjectProperty cssColorProperty() { return cssColorProperty; } private static final CssMetaData<TriangleLabel, Color> COLOR_META_DATA = JavaFXUtil.cssColor("-bj-fill-color", TriangleLabel::cssColorProperty); private static final List <CssMetaData <? extends Styleable, ? > > cssMetaDataList = JavaFXUtil.extendCss(HBox.getClassCssMetaData()) .add(COLOR_META_DATA) .build(); public static List > getClassCssMetaData() { return cssMetaDataList; } @Override public List> getCssMetaData() { return getClassCssMetaData(); } public TriangleLabel(InteractionManager editor, FXConsumer<SharedTransition> expand, FXConsumer<SharedTransition> shrink, SimpleBooleanProperty showing) { this.expanded = showing; JavaFXUtil.addChangeListener(cssColorProperty, c -> { GraphicsContext g = this.canvas.getGraphicsContext2D(); g.clearRect(0, 0, this.canvas.getWidth(), this.canvas.getHeight()); g.setFill(c); g.fillPolygon(new double[] {1, 7, 1 }, new double[] {1, 5, 9 }, 3); }); JavaFXUtil.addStyleClass(this, "triangle-label"); getChildren().add(this.canvas); setAlignment(Pos.BASELINE_LEFT); setFillHeight(false); addEventFilter(MouseEvent.MOUSE_CLICKED, e -> { expanded.set(!expanded.get()); e.consume(); }); JavaFXUtil.addChangeListener(expanded, new FXConsumer<Boolean>() { private SharedTransition transition = null; @Override public void accept(Boolean nowExpanded) { if (nowExpanded) { JavaFXUtil.runNowOrLater(() -> animate(true)); } else { JavaFXUtil.runNowOrLater(() -> { animate(false); editor.getSelection().clear(); }); } } @OnThread(Tag.FXPlatform) private void animate(boolean expandAnim) { if (transition != null) { transition.stop(); transition = null; } transition = new SharedTransition(); if (expandAnim) expand.accept(transition); else{ shrink.accept(transition); } canvas.rotateProperty().bind((expandAnim ? transition.getProgress() : transition.getOppositeProgress()).multiply(90.0)); transition.addOnStopped(canvas.rotateProperty()::unbind); transition.animateOver(Duration.millis(200)); } }); } @Override public ObservableList getComponents() { return FXCollections.observableArrayList(this); } @Override public EditableSlot asEditable() { return null; } public SimpleBooleanProperty expandedProperty() { return expanded; } @Override public void setView(Frame.View oldView, Frame.View newView, SharedTransition animate) { } }
top, use, map, class TriangleLabel

.   cssColorProperty
.   getClassCssMetaData
.   getCssMetaData
.   TriangleLabel
.   accept
.   animate
.   getComponents
.   asEditable
.   expandedProperty
.   setView




152 neLoCode + 5 LoComm