Package lighthouse.controls

Source Code of lighthouse.controls.NotificationBarPane$Item

package lighthouse.controls;


import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableDoubleValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.util.Duration;
import lighthouse.protocol.LHUtils;
import lighthouse.utils.GuiUtils;
import lighthouse.utils.easing.EasingMode;
import lighthouse.utils.easing.ElasticInterpolator;

import javax.annotation.Nullable;

/**
* Wraps the given Node in a BorderPane and allows a thin bar to slide in from the bottom or top, squeezing the content
* node. The API allows different "items" to be added/removed and they will be displayed one at a time, fading between
* them when the topmost is removed. Each item is meant to be used for e.g. a background task and can contain a button
* and/or a progress bar.
*/
public class NotificationBarPane extends BorderPane {
    public static final Duration ANIM_IN_DURATION = GuiUtils.UI_ANIMATION_TIME.multiply(2);
    public static final Duration ANIM_OUT_DURATION = GuiUtils.UI_ANIMATION_TIME;

    private VBox bar;
    private double barHeight;

    public class Item {
        public final StringProperty label;
        @Nullable public final ObservableDoubleValue progress;

        protected HBox entry;
        private Label labelControl;
        @Nullable private ProgressBar progressBar;

        public Item(String initialLabel, @Nullable ObservableDoubleValue progress, @Nullable Button button) {
            this.progress = progress;

            labelControl = new Label();
            labelControl.setText(initialLabel);
            labelControl.setMaxWidth(Double.MAX_VALUE);
            HBox.setHgrow(labelControl, Priority.ALWAYS);
            label = labelControl.textProperty();
            entry = new HBox(labelControl);
            if (progress != null) {
                progressBar = new ProgressBar();
                progressBar.setMinWidth(200);
                progressBar.progressProperty().bind(progress);
                entry.getChildren().add(progressBar);
            }
            if (button != null) {
                entry.getChildren().add(button);
            }
            entry.getStyleClass().add("notification-bar-item");
            entry.setFillHeight(true);
            entry.setAlignment(Pos.CENTER_LEFT);
        }

        public void cancel() {
            items.remove(this);
        }
    }

    public final ObservableList<Item> items;

    public NotificationBarPane(Node content) {
        super(content);

        // Just for sizing
        Item fakeItem = new Item("infobar!", null, new Button("foo"));
        bar = new VBox(fakeItem.entry);
        bar.setMinHeight(0.0);
        bar.getStyleClass().add("info-bar");
        bar.setFillWidth(true);
        setBottom(bar);
        // Figure out the height of the bar based on the CSS. Must wait until after we've been added to the parent node.
        sceneProperty().addListener(o -> {
            if (getParent() == null) return;
            getParent().applyCss();
            getParent().layout();
            barHeight = bar.getHeight();
            bar.setPrefHeight(0.0);
            bar.getChildren().remove(fakeItem.entry);
        });
        items = FXCollections.observableArrayList();
        items.addListener(this::processItemChange);
    }

    private void processItemChange(ListChangeListener.Change<? extends Item> change) {
        while (change.next()) {
            if (change.wasRemoved()) {
                bar.getChildren().removeAll(LHUtils.mapList(change.getRemoved(), item -> item.entry));
            }
            if (change.wasAdded()) {
                bar.getChildren().addAll(LHUtils.mapList(change.getAddedSubList(), item -> item.entry));
            }
        }
        showOrHide();
    }

    private void showOrHide() {
        if (items.isEmpty())
            animateOut();
        else
            animateIn();
    }

    public boolean isShowing() {
        return bar.getPrefHeight() > 0;
    }

    private void animateIn() {
        animate(barHeight * items.size());
    }

    private void animateOut() {
        animate(0.0);
    }

    private Timeline timeline;
    protected void animate(Number target) {
        if (timeline != null) {
            timeline.stop();
            timeline = null;
        }
        Duration duration;
        Interpolator interpolator;
        if (target.intValue() > 0) {
            interpolator = new ElasticInterpolator(EasingMode.EASE_OUT, 1, 2);
            duration = ANIM_IN_DURATION;
        } else {
            interpolator = Interpolator.EASE_OUT;
            duration = ANIM_OUT_DURATION;
        }
        KeyFrame kf = new KeyFrame(duration, new KeyValue(bar.prefHeightProperty(), target, interpolator));
        timeline = new Timeline(kf);
        timeline.setOnFinished(x -> timeline = null);
        timeline.play();
    }

    public Item displayNewItem(String string) {
        Item item = createItem(string, null, null);
        items.add(item);
        return item;
    }

    public Item displayNewItem(String string, ObservableDoubleValue progress) {
        Item item = createItem(string, progress);
        items.add(item);
        return item;
    }

    public Item displayNewItem(String string, Button btn) {
        Item item = createItem(string, btn);
        items.add(item);
        return item;
    }

    public Item createItem(String string, @Nullable ObservableDoubleValue progress) {
        return new Item(string, progress, null);
    }

    public Item createItem(String string, @Nullable Button button) {
        return new Item(string, null, button);
    }

    public Item createItem(String string, @Nullable ObservableDoubleValue progress, @Nullable Button button) {
        return new Item(string, progress, button);
    }
}
TOP

Related Classes of lighthouse.controls.NotificationBarPane$Item

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.