Package eu.hansolo.enzo.radialmenu

Source Code of eu.hansolo.enzo.radialmenu.RadialMenu$ItemEvent

/*
* Copyright (c) 2013 by Gerrit Grunwald
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package eu.hansolo.enzo.radialmenu;

import eu.hansolo.enzo.common.Symbol;
import eu.hansolo.enzo.common.SymbolType;
import javafx.animation.FadeTransition;
import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.ParallelTransition;
import javafx.animation.RotateTransition;
import javafx.animation.ScaleTransition;
import javafx.animation.Timeline;
import javafx.animation.Transition;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ObjectPropertyBase;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableMap;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventTarget;
import javafx.event.EventType;
import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.util.Duration;

import java.util.*;


/**
* Created with IntelliJ IDEA.
* User: hansolo
* Date: 21.09.12
* Time: 13:25
* To change this template use File | Settings | File Templates.
*/
public class RadialMenu extends Region {
    public static enum State {
        OPENED,
        CLOSED
    }

    private ObservableMap<Parent, MenuItem> items;
    private State                           defaultState;
    private ObjectProperty<State>           state;
    private double                          degrees;
    private int                             positions;
    private Timeline[]                      openTimeLines;
    private Timeline[]                      closeTimeLines;
    private Options                         options;
    private MenuButton                      mainMenuButton;
    private Group                           cross;
    private boolean                         firstTime;
    private EventHandler<MouseEvent>        mouseHandler;


    // ******************** Constructors **************************************
    public RadialMenu(final Options OPTIONS, final MenuItem... ITEMS) {
        this(OPTIONS, Arrays.asList(ITEMS));
    }
    public RadialMenu(final Options OPTIONS, final List<MenuItem> ITEMS) {
        options               = OPTIONS;
        items                 = FXCollections.observableHashMap();
        getStylesheets().add(getClass().getResource("radialmenu.css").toExternalForm());
        getStyleClass().addAll("radial-menu");
        state                 = new SimpleObjectProperty<>(this, "state", State.CLOSED);
        degrees               = Math.max(Math.min(360, options.getDegrees()), 0);
        cross                 = new Group();
        firstTime             = true;
        initHandler();
        initMainButton();
        initMenuItems(ITEMS);
        initGraphics();
        registerListeners();
    }


    // ******************** Initialization ************************************
    private void initMainButton() {
        // Define main menu button
        mainMenuButton = new MenuButton(this);
        mainMenuButton.setPrefSize(options.getButtonSize(), options.getButtonSize());
    }

    private void initMenuItems(final List<MenuItem> ITEMS) {
        Map<Parent, MenuItem> itemMap = new HashMap<>(ITEMS.size());
        positions      = Double.compare(degrees, 360.0) == 0 ? ITEMS.size() : ITEMS.size() - 1;
        openTimeLines  = new Timeline[ITEMS.size()];
        closeTimeLines = new Timeline[ITEMS.size()];

        for (int i = 0 ; i < ITEMS.size() ; i++) {
            MenuItem item = ITEMS.get(i);
            item.setPrefSize(item.getSize() * 0.77778, item.getSize() * 0.77778);

            // Create graphical representation of each menu item
            final StackPane ITEM_CONTAINER = new StackPane();
            ITEM_CONTAINER.getChildren().add(item);

            if (SymbolType.NONE == item.getSymbolType() && item.getThumbnailImageName().isEmpty()) {
                Text text = new Text(item.getText());
                text.setFont(Font.font("Open Sans", FontWeight.BOLD, item.getSize() * 0.5));
                text.setFill(item.getForegroundColor());
                text.setMouseTransparent(true);
                ITEM_CONTAINER.getChildren().add(text);
            } else if (!item.getThumbnailImageName().isEmpty()) {
                try {
                    ITEM_CONTAINER.getChildren().add(createThumbnail(item));
                } catch (IllegalArgumentException exception) {
                    Text text = new Text(Integer.toString(i));
                    text.setFont(Font.font("Open Sans", FontWeight.BOLD, item.getSize() * 0.5));
                    text.setFill(item.getForegroundColor());
                    text.setMouseTransparent(true);
                    ITEM_CONTAINER.getChildren().add(text);
                }
            } else {
                Symbol symbol = new Symbol(item.getSymbolType(), 0.5 * item.getSize(), Color.WHITE, Symbol.NOT_RESIZEABLE);
                symbol.setMouseTransparent(true);
                ITEM_CONTAINER.getChildren().add(symbol);
            }

            ITEM_CONTAINER.setPickOnBounds(false);
            ITEM_CONTAINER.setOpacity(0.0);

            // Add animations for each menu item
            double  degree    = (((degrees / positions) * i) + options.getOffset()) % 360;
            Point2D position  = new Point2D(Math.cos(Math.toRadians(degree)), Math.sin(Math.toRadians(degree)));
            double x          = Math.round(position.getX() * options.getRadius());
            double y          = Math.round(position.getY() * options.getRadius());
            double delay      = (200 / ITEMS.size()) * i;

            openTimeLines[i= options.isSimpleMode() ? createSimpleItemOpenTimeLine(ITEM_CONTAINER, x, y, delay) : createItemOpenTimeLine(ITEM_CONTAINER, x, y, delay);
            closeTimeLines[i] = options.isSimpleMode() ? createSimpleItemCloseTimeLine(ITEM_CONTAINER, x, y, delay) : createItemCloseTimeLine(ITEM_CONTAINER, x, y, delay);

            // Add mouse event handler to each item
            ITEM_CONTAINER.setOnMousePressed(mouseHandler);
            ITEM_CONTAINER.setOnMouseReleased(mouseHandler);

            // Add items and nodes to map
            itemMap.put(ITEM_CONTAINER, item);
        }
        items.putAll(itemMap);
    }

    private void initGraphics() {
        getChildren().setAll(items.keySet());
        getChildren().add(mainMenuButton);
    }

    private void initHandler() {
        mouseHandler          = mouseEvent -> {
            final Object SOURCE = mouseEvent.getSource();
            if (MouseEvent.MOUSE_PRESSED == mouseEvent.getEventType()) {
                MenuItem menuItem = items.get(SOURCE);
                if (menuItem.isSelectable()) {
                    menuItem.setSelected(!menuItem.isSelected());
                    if (menuItem.isSelected()) {
                        fireItemEvent(new ItemEvent(menuItem, this, null, ItemEvent.ITEM_SELECTED));
                    } else {
                        fireItemEvent(new ItemEvent(menuItem, this, null, ItemEvent.ITEM_DESELECTED));
                    }
                } else {
                    click(menuItem);
                    fireItemEvent(new ItemEvent(menuItem, this, null, ItemEvent.ITEM_CLICKED));
                }
            }
        };
    }

    private void registerListeners() {
        widthProperty().addListener(observable -> resize());
        heightProperty().addListener(observable -> resize());
        mainMenuButton.openProperty().addListener(observable -> {
            if (mainMenuButton.isOpen()) {
                fireMenuEvent(new RadialMenu.MenuEvent(this, this, MenuEvent.MENU_OPEN_STARTED));
                open();
            } else {
                fireMenuEvent(new RadialMenu.MenuEvent(this, this, MenuEvent.MENU_CLOSE_STARTED));
                close();
            }
        });
    }


    // ******************** Methods *******************************************
    @Override public void layoutChildren() {
        super.layoutChildren();
        if (firstTime) {
            resize();
            firstTime = false;
        }
    }

    public final State getState() {
        return null == state ? defaultState : state.get();
    }
    private final void setState(final State STATE) {
        if (null == state) {
            defaultState = STATE;
        } else {
            state.set(STATE);
        }
    }
    public final ReadOnlyObjectProperty<State> stateProperty() {
        if (null == state) {
            state = new SimpleObjectProperty<>(this, "state", defaultState);
        }
        return state;
    }

    public MenuItem getItem(final int INDEX) {
        if (INDEX < 0 || INDEX > items.size()) {
            throw new IndexOutOfBoundsException();
        }
        return getItems().get(INDEX);
    }
    public void addItem(final MenuItem ITEM) {
        List<MenuItem> tmpItems = new LinkedList<>(items.values());
        tmpItems.add(ITEM);
        initMenuItems(tmpItems);
        initGraphics();
    }
    public void removeItem(final MenuItem ITEM) {
        if (!items.values().contains(ITEM)) {
            return;
        }
        List<MenuItem> tmpItems = (List<MenuItem>) items.values();
        tmpItems.remove(ITEM);
        initMenuItems(tmpItems);
        initGraphics();
    }
    public List<MenuItem> getItems() {
        List<MenuItem> tmpList = new ArrayList<>(items.size());
        for (MenuItem item : items.values()) {
            tmpList.add(item);
        }
        return tmpList;
    }

    protected Options getOptions() {
        return options;
    }

    public void open() {
        if (!mainMenuButton.isOpen()) mainMenuButton.setOpen(true);
        if (!options.isButtonHideOnSelect()) {
            show();
        }

        if (State.OPENED == getState()) {
            return;
        }
        setState(State.OPENED);
        mainMenuButton.setOpacity(1.0);
        openTimeLines[openTimeLines.length - 1].setOnFinished(actionEvent -> fireMenuEvent(new MenuEvent(this, null, MenuEvent.MENU_OPEN_FINISHED)));
        for (int i = 0 ; i < openTimeLines.length ; i++) {
            openTimeLines[i].play();
        }
    }
    public void close() {
        if (State.CLOSED == getState()) return;

        setState(State.CLOSED);
        RotateTransition rotate = new RotateTransition();
        rotate.setNode(cross);
        rotate.setToAngle(0);
        rotate.setDuration(Duration.millis(200));
        rotate.setInterpolator(Interpolator.EASE_BOTH);
        rotate.play();
        closeTimeLines[closeTimeLines.length - 1].setOnFinished(actionEvent -> {
            FadeTransition buttonFadeOut = new FadeTransition();
            buttonFadeOut.setNode(mainMenuButton);
            buttonFadeOut.setDuration(Duration.millis(100));
            buttonFadeOut.setToValue(options.getButtonAlpha());
            buttonFadeOut.play();
            buttonFadeOut.setOnFinished(event -> {
                if (options.isButtonHideOnClose()) hide();
                fireMenuEvent(new MenuEvent(this, null, MenuEvent.MENU_CLOSE_FINISHED));
            });
        });
        for (int i = 0 ; i < closeTimeLines.length ; i++) {
            closeTimeLines[i].play();
        }
        fireMenuEvent(new MenuEvent(this, null, MenuEvent.MENU_CLOSE_STARTED));
    }

    public void show() {
        if (options.isButtonHideOnSelect() && mainMenuButton.getOpacity() > 0) {
            return;
        }

        if (options.isButtonHideOnSelect() || mainMenuButton.getOpacity() == 0) {
            mainMenuButton.setScaleX(1.0);
            mainMenuButton.setScaleY(1.0);
            cross.setRotate(0);
            mainMenuButton.setRotate(0);

            FadeTransition buttonFadeIn = new FadeTransition();
            buttonFadeIn.setNode(mainMenuButton);
            buttonFadeIn.setDuration(Duration.millis(200));
            buttonFadeIn.setToValue(options.getButtonAlpha());
            buttonFadeIn.play();
        }
        for (Parent node : items.keySet()) {
            node.setScaleX(1.0);
            node.setScaleY(1.0);
            node.setTranslateX(0);
            node.setTranslateY(0);
            node.setRotate(0);
        }
    }
    public void hide() {
        setState(State.CLOSED);
        mainMenuButton.setOpacity(0.0);
        mainMenuButton.setOpen(false);
        for (Parent node : items.keySet()) {
            node.setOpacity(0);
        }
    }

    public void click(final MenuItem CLICKED_ITEM) {
        List<Transition> transitions = new ArrayList<>(items.size() * 2);
        for (Parent node : items.keySet()) {
            if (items.get(node).equals(CLICKED_ITEM)) {
                // Add enlarge transition to selected item
                ScaleTransition enlargeItem = new ScaleTransition(Duration.millis(300), node);
                enlargeItem.setToX(5.0);
                enlargeItem.setToY(5.0);
                transitions.add(enlargeItem);
            } else {
                // Add shrink transition to all other items
                ScaleTransition shrinkItem = new ScaleTransition(Duration.millis(300), node);
                shrinkItem.setToX(0.0);
                shrinkItem.setToY(0.0);
                transitions.add(shrinkItem);
            }
            // Add fade out transition to every node
            FadeTransition fadeOutItem = new FadeTransition(Duration.millis(300), node);
            fadeOutItem.setToValue(0.0);
            transitions.add(fadeOutItem);
        }

        // Add rotate and fade transition to main menu button
        if (options.isButtonHideOnSelect()) {
            RotateTransition rotateMainButton = new RotateTransition(Duration.millis(300), mainMenuButton);
            rotateMainButton.setToAngle(225);
            transitions.add(rotateMainButton);
            FadeTransition fadeOutMainButton = new FadeTransition(Duration.millis(300), mainMenuButton);
            fadeOutMainButton.setToValue(0.0);
            transitions.add(fadeOutMainButton);
            ScaleTransition shrinkMainButton = new ScaleTransition(Duration.millis(300), mainMenuButton);
            shrinkMainButton.setToX(0.0);
            shrinkMainButton.setToY(0.0);
            transitions.add(shrinkMainButton);
        } else {
            RotateTransition rotateBackMainButton = new RotateTransition();
            rotateBackMainButton.setNode(cross);
            rotateBackMainButton.setToAngle(0);
            rotateBackMainButton.setDuration(Duration.millis(200));
            rotateBackMainButton.setInterpolator(Interpolator.EASE_BOTH);
            transitions.add(rotateBackMainButton);
            FadeTransition mainButtonFadeOut = new FadeTransition();
            mainButtonFadeOut.setNode(mainMenuButton);
            mainButtonFadeOut.setDuration(Duration.millis(100));
            mainButtonFadeOut.setToValue(options.getButtonAlpha());
            transitions.add(mainButtonFadeOut);
        }

        // Play all transitions in parallel
        ParallelTransition selectTransition = new ParallelTransition();
        selectTransition.getChildren().addAll(transitions);
        selectTransition.play();

        // Set menu state back to closed
        setState(State.CLOSED);
        mainMenuButton.setOpen(false);
    }

    private ImageView createThumbnail(final MenuItem ITEM) {
        ImageView imageItem = new ImageView(new Image(ITEM.getThumbnailImageName()));
        imageItem.setFitWidth(ITEM.getSize() * 0.5);
        imageItem.setFitHeight(ITEM.getSize() * 0.5);
        imageItem.setMouseTransparent(true);

        return imageItem;
    }

    private Timeline createItemOpenTimeLine(final StackPane NODE, final double X, final double Y, final double DELAY) {
        KeyValue kvX1  = new KeyValue(NODE.translateXProperty(), 0, Interpolator.EASE_OUT);
        KeyValue kvY1  = new KeyValue(NODE.translateYProperty(), 0, Interpolator.EASE_OUT);
        KeyValue kvR1  = new KeyValue(NODE.rotateProperty(), 0, Interpolator.EASE_OUT);
        KeyValue kvO1  = new KeyValue(NODE.opacityProperty(), 0.0, Interpolator.EASE_OUT);

        KeyValue kvX2  = new KeyValue(NODE.translateXProperty(), 0.0);
        KeyValue kvY2  = new KeyValue(NODE.translateYProperty(), 0.0);

        KeyValue kvX3  = new KeyValue(NODE.translateXProperty(), 1.1 * X, Interpolator.EASE_IN);
        KeyValue kvY3  = new KeyValue(NODE.translateYProperty(), 1.1 * Y, Interpolator.EASE_IN);

        KeyValue kvX4  = new KeyValue(NODE.translateXProperty(), 0.95 * X, Interpolator.EASE_OUT);
        KeyValue kvY4  = new KeyValue(NODE.translateYProperty(), 0.95 * Y, Interpolator.EASE_OUT);
        KeyValue kvRO4 = new KeyValue(NODE.rotateProperty(), 360);
        KeyValue kvO4  = new KeyValue(NODE.opacityProperty(), 1.0, Interpolator.EASE_OUT);

        KeyValue kvX5  = new KeyValue(NODE.translateXProperty(), X);
        KeyValue kvY5  = new KeyValue(NODE.translateYProperty(), Y);

        KeyFrame kfO1  = new KeyFrame(Duration.millis(0), kvX1, kvY1, kvR1, kvO1);
        KeyFrame kfO2  = new KeyFrame(Duration.millis(50 + DELAY), kvX2, kvY2);
        KeyFrame kfO3  = new KeyFrame(Duration.millis(250 + DELAY), kvX3, kvY3);
        KeyFrame kfO4  = new KeyFrame(Duration.millis(400 + DELAY), kvX4, kvY4, kvRO4, kvO4);
        KeyFrame kfO5  = new KeyFrame(Duration.millis(550 + DELAY), kvX5, kvY5);

        return new Timeline(kfO1, kfO2, kfO3, kfO4, kfO5);
    }
    private Timeline createItemCloseTimeLine(final StackPane NODE, final double X, final double Y, final double DELAY) {
        KeyValue kvX1  = new KeyValue(NODE.translateXProperty(), X);
        KeyValue kvY1  = new KeyValue(NODE.translateYProperty(), Y);

        KeyValue kvRC2 = new KeyValue(NODE.rotateProperty(), 720);

        KeyValue kvX3  = new KeyValue(NODE.translateXProperty(), X, Interpolator.EASE_IN);
        KeyValue kvY3  = new KeyValue(NODE.translateYProperty(), Y, Interpolator.EASE_IN);

        KeyValue kvX4  = new KeyValue(NODE.translateXProperty(), 0);
        KeyValue kvY4  = new KeyValue(NODE.translateYProperty(), 0);

        KeyValue kvX5  = new KeyValue(NODE.translateXProperty(), 0, Interpolator.EASE_OUT);
        KeyValue kvY5  = new KeyValue(NODE.translateYProperty(), 0, Interpolator.EASE_OUT);
        KeyValue kvR5  = new KeyValue(NODE.rotateProperty(), 0, Interpolator.EASE_OUT);
        KeyValue kvO5  = new KeyValue(NODE.opacityProperty(), 0.5);

        KeyValue kvO6  = new KeyValue(NODE.opacityProperty(), 0);

        KeyFrame kfC1  = new KeyFrame(Duration.millis(0), kvX1, kvY1);
        KeyFrame kfC2  = new KeyFrame(Duration.millis(50 + DELAY), kvRC2);
        KeyFrame kfC3  = new KeyFrame(Duration.millis(250 + DELAY), kvX3, kvY3);
        KeyFrame kfC4  = new KeyFrame(Duration.millis(400 + DELAY), kvX4, kvY4);
        KeyFrame kfC5  = new KeyFrame(Duration.millis(550 + DELAY), kvX5, kvY5, kvR5, kvO5);
        KeyFrame kfC6  = new KeyFrame(Duration.millis(551 + DELAY), kvO6);

        return new Timeline(kfC1, kfC2, kfC3, kfC4, kfC5, kfC6);
    }

    private Timeline createSimpleItemOpenTimeLine(final StackPane NODE, final double X, final double Y, final double DELAY) {
        KeyValue kvX1  = new KeyValue(NODE.translateXProperty(), 0, Interpolator.EASE_OUT);
        KeyValue kvY1  = new KeyValue(NODE.translateYProperty(), 0, Interpolator.EASE_OUT);
        KeyValue kvR1  = new KeyValue(NODE.rotateProperty(), 0, Interpolator.EASE_OUT);
        KeyValue kvO1  = new KeyValue(NODE.opacityProperty(), 0, Interpolator.EASE_OUT);

        KeyValue kvX2  = new KeyValue(NODE.translateXProperty(), 0.0);
        KeyValue kvY2  = new KeyValue(NODE.translateYProperty(), 0.0);

        KeyValue kvX3  = new KeyValue(NODE.translateXProperty(), 1.1 * X, Interpolator.EASE_IN);
        KeyValue kvY3  = new KeyValue(NODE.translateYProperty(), 1.1 * Y, Interpolator.EASE_IN);

        KeyValue kvX4  = new KeyValue(NODE.translateXProperty(), 0.97 * X, Interpolator.EASE_OUT);
        KeyValue kvY4  = new KeyValue(NODE.translateYProperty(), 0.97 * Y, Interpolator.EASE_OUT);
        KeyValue kvRO4 = new KeyValue(NODE.rotateProperty(), 360);
        KeyValue kvO4  = new KeyValue(NODE.opacityProperty(), 1.0, Interpolator.EASE_OUT);

        KeyValue kvX5  = new KeyValue(NODE.translateXProperty(), X);
        KeyValue kvY5  = new KeyValue(NODE.translateYProperty(), Y);

        KeyFrame kfO1  = new KeyFrame(Duration.millis(0), kvX1, kvY1, kvR1, kvO1);
        KeyFrame kfO2  = new KeyFrame(Duration.millis(50 + DELAY), kvX2, kvY2);
        KeyFrame kfO3  = new KeyFrame(Duration.millis(150 + DELAY), kvX3, kvY3);
        KeyFrame kfO4  = new KeyFrame(Duration.millis(300 + DELAY), kvX4, kvY4, kvRO4, kvO4);
        KeyFrame kfO5  = new KeyFrame(Duration.millis(400 + DELAY), kvX5, kvY5);

        return new Timeline(kfO1, kfO2, kfO3, kfO4, kfO5);
    }
    private Timeline createSimpleItemCloseTimeLine(final StackPane NODE, final double X, final double Y, final double DELAY) {
        KeyValue kvX1  = new KeyValue(NODE.translateXProperty(), X);
        KeyValue kvY1  = new KeyValue(NODE.translateYProperty(), Y);

        KeyValue kvRC2 = new KeyValue(NODE.rotateProperty(), 360);

        KeyValue kvX3  = new KeyValue(NODE.translateXProperty(), 1.0 * X, Interpolator.EASE_IN);
        KeyValue kvY3  = new KeyValue(NODE.translateYProperty(), 1.0 * Y, Interpolator.EASE_IN);

        KeyValue kvX4  = new KeyValue(NODE.translateXProperty(), 0.0);
        KeyValue kvY4  = new KeyValue(NODE.translateYProperty(), 0.0);

        KeyValue kvX5  = new KeyValue(NODE.translateXProperty(), 0, Interpolator.EASE_OUT);
        KeyValue kvY5  = new KeyValue(NODE.translateYProperty(), 0, Interpolator.EASE_OUT);
        KeyValue kvR5  = new KeyValue(NODE.rotateProperty(), 0, Interpolator.EASE_OUT);
        KeyValue kvO5  = new KeyValue(NODE.opacityProperty(), 0.5);

        KeyValue kvO6  = new KeyValue(NODE.opacityProperty(), 0);

        KeyFrame kfC1  = new KeyFrame(Duration.millis(0), kvX1, kvY1);
        KeyFrame kfC2  = new KeyFrame(Duration.millis(50 + DELAY), kvRC2);
        KeyFrame kfC3  = new KeyFrame(Duration.millis(250 + DELAY), kvX3, kvY3);
        KeyFrame kfC4  = new KeyFrame(Duration.millis(400 + DELAY), kvX4, kvY4);
        KeyFrame kfC5  = new KeyFrame(Duration.millis(550 + DELAY), kvX5, kvY5, kvR5, kvO5);
        KeyFrame kfC6  = new KeyFrame(Duration.millis(551 + DELAY), kvO6);

        return new Timeline(kfC1, kfC2, kfC3, kfC4, kfC5, kfC6);
    }

    private void resize() {
        mainMenuButton.relocate((getPrefWidth() - options.getButtonSize()) * 0.5, (getPrefHeight() - options.getButtonSize()) * 0.5);
        for (Parent node : items.keySet()) {
            node.setLayoutX((getPrefWidth() - node.getLayoutBounds().getWidth()) * 0.5);
            node.setLayoutY((getPrefHeight() - node.getLayoutBounds().getHeight()) * 0.5);
        }
    }


    // ******************** Event handling ************************************
    public final ObjectProperty<EventHandler<ItemEvent>> onItemClickedProperty() { return onItemClicked; }
    public final void setOnItemClicked(EventHandler<ItemEvent> value) { onItemClickedProperty().set(value); }
    public final EventHandler<ItemEvent> getOnItemClicked() { return onItemClickedProperty().get(); }
    private ObjectProperty<EventHandler<ItemEvent>> onItemClicked = new ObjectPropertyBase<EventHandler<ItemEvent>>() {
        @Override public Object getBean() { return this; }
        @Override public String getName() { return "onItemClicked";}
    };

    public final ObjectProperty<EventHandler<ItemEvent>> onItemSelectedProperty() { return onItemSelected; }
    public final void setOnItemSelected(EventHandler<ItemEvent> value) { onItemSelectedProperty().set(value); }
    public final EventHandler<ItemEvent> getOnItemSelected() { return onItemSelectedProperty().get(); }
    private ObjectProperty<EventHandler<ItemEvent>> onItemSelected = new ObjectPropertyBase<EventHandler<ItemEvent>>() {
        @Override public Object getBean() { return this; }
        @Override public String getName() { return "onItemSelected";}
    };

    public final ObjectProperty<EventHandler<ItemEvent>> onItemDeselectedProperty() { return onItemDeselected; }
    public final void setOnItemDeselected(EventHandler<ItemEvent> value) { onItemDeselectedProperty().set(value); }
    public final EventHandler<ItemEvent> getOnItemDeselected() { return onItemDeselectedProperty().get(); }
    private ObjectProperty<EventHandler<ItemEvent>> onItemDeselected = new ObjectPropertyBase<EventHandler<ItemEvent>>() {
        @Override public Object getBean() { return this; }
        @Override public String getName() { return "onItemDeselected";}
    };

    public void fireItemEvent(final ItemEvent EVENT) {
        fireEvent(EVENT);

        final EventType TYPE = EVENT.getEventType();
        final EventHandler<ItemEvent> HANDLER;
        if (ItemEvent.ITEM_CLICKED == TYPE) {
            HANDLER = getOnItemClicked();
        } else if (ItemEvent.ITEM_SELECTED == TYPE) {
            HANDLER = getOnItemSelected();
        } else if (ItemEvent.ITEM_DESELECTED == TYPE) {
           HANDLER = getOnItemDeselected();
        } else {
            HANDLER = null;
        }

        if (HANDLER != null) {
            HANDLER.handle(EVENT);
        }
    }

    public final ObjectProperty<EventHandler<MenuEvent>> onMenuOpenStartedProperty() { return onMenuOpenStarted; }
    public final void setOnMenuOpenStarted(EventHandler<MenuEvent> value) { onMenuOpenStartedProperty().set(value); }
    public final EventHandler<MenuEvent> getOnMenuOpenStarted() { return onMenuOpenStartedProperty().get(); }
    private ObjectProperty<EventHandler<MenuEvent>> onMenuOpenStarted = new ObjectPropertyBase<EventHandler<MenuEvent>>() {
        @Override public Object getBean() { return this; }
        @Override public String getName() { return "onMenuOpenStarted";}
    };

    public final ObjectProperty<EventHandler<MenuEvent>> onMenuOpenFinishedProperty() { return onMenuOpenFinished; }
    public final void setOnMenuOpenFinished(EventHandler<MenuEvent> value) { onMenuOpenFinishedProperty().set(value); }
    public final EventHandler<MenuEvent> getOnMenuOpenFinished() { return onMenuOpenFinishedProperty().get(); }
    private ObjectProperty<EventHandler<MenuEvent>> onMenuOpenFinished = new ObjectPropertyBase<EventHandler<MenuEvent>>() {
        @Override public Object getBean() { return this; }
        @Override public String getName() { return "onMenuOpenFinished";}
    };

    public final ObjectProperty<EventHandler<MenuEvent>> onMenuCloseStartedProperty() { return onMenuCloseStarted; }
    public final void setOnMenuCloseStarted(EventHandler<MenuEvent> value) { onMenuCloseStartedProperty().set(value); }
    public final EventHandler<MenuEvent> getOnMenuCloseStarted() { return onMenuCloseStartedProperty().get(); }
    private ObjectProperty<EventHandler<MenuEvent>> onMenuCloseStarted = new ObjectPropertyBase<EventHandler<MenuEvent>>() {
        @Override public Object getBean() { return this; }
        @Override public String getName() { return "onMenuCloseStarted";}
    };

    public final ObjectProperty<EventHandler<MenuEvent>> onMenuCloseFinishedProperty() { return onMenuCloseFinished; }
    public final void setOnMenuCloseFinished(EventHandler<MenuEvent> value) { onMenuCloseFinishedProperty().set(value); }
    public final EventHandler<MenuEvent> getOnMenuCloseFinished() { return onMenuCloseFinishedProperty().get(); }
    private ObjectProperty<EventHandler<MenuEvent>> onMenuCloseFinished = new ObjectPropertyBase<EventHandler<MenuEvent>>() {
        @Override public Object getBean() { return this; }
        @Override public String getName() { return "onMenuCloseFinished";}
    };

    public void fireMenuEvent(final MenuEvent EVENT) {
        fireEvent(EVENT);

        final EventType TYPE = EVENT.getEventType();
        final EventHandler<MenuEvent> HANDLER;

        if (MenuEvent.MENU_OPEN_STARTED == TYPE) {
            HANDLER = getOnMenuOpenStarted();
        } else if (MenuEvent.MENU_OPEN_FINISHED == TYPE) {
            HANDLER = getOnMenuOpenFinished();
        } else if (MenuEvent.MENU_CLOSE_STARTED == TYPE) {
            HANDLER = getOnMenuCloseStarted();
        } else if (MenuEvent.MENU_CLOSE_FINISHED == TYPE) {
            HANDLER = getOnMenuCloseFinished();
        } else {
            HANDLER = null;
        }

        if (HANDLER != null) {
            HANDLER.handle(EVENT);
        }
    }


    // ******************** Inner classes *************************************
    public static class ItemEvent extends Event {
        public static final EventType<ItemEvent> ITEM_CLICKED    = new EventType(ANY, "itemClicked");
        public static final EventType<ItemEvent> ITEM_SELECTED   = new EventType(ANY, "itemSelected");
        public static final EventType<ItemEvent> ITEM_DESELECTED = new EventType(ANY, "itemDeselected");

        public MenuItem item;


        // ******************** Constructors **********************************
        public ItemEvent(final MenuItem ITEM, final Object SOURCE, final EventTarget TARGET, final EventType<ItemEvent> EVENT_TYPE) {
            super(SOURCE, TARGET, EVENT_TYPE);
            item = ITEM;
        }

    }

    public static class MenuEvent extends Event {
        public static final EventType<MenuEvent> MENU_OPEN_STARTED   = new EventType(ANY, "menuOpenStarted");
        public static final EventType<MenuEvent> MENU_OPEN_FINISHED  = new EventType(ANY, "menuOpenFinished");
        public static final EventType<MenuEvent> MENU_CLOSE_STARTED  = new EventType(ANY, "menuCloseStarted");
        public static final EventType<MenuEvent> MENU_CLOSE_FINISHED = new EventType(ANY, "menuCloseFinished");

        // ******************** Constructors **********************************
        public MenuEvent(final Object SOURCE, final EventTarget TARGET, final EventType<MenuEvent> EVENT_TYPE) {
            super(SOURCE, TARGET, EVENT_TYPE);
        }
    }
}
TOP

Related Classes of eu.hansolo.enzo.radialmenu.RadialMenu$ItemEvent

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.