/* * ShootOFF - Software for Laser Dry Fire Training * Copyright (C) 2016 phrack * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.shootoff.gui.pane; import java.util.ArrayList; import java.util.List; import java.util.Optional; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.Pane; public abstract class Slide { // We set a maximum on the number of control buttons at the top // because we want them to always maintain the same alighment and // size. If slide had more than the maximum, it would break // the size and alignment invariant. public static final int MAX_CONTROL_BUTTONS = 4; public static final int CONTROL_BUTTON_WIDTH = 150; public static final int CONTROL_BUTTON_HEIGHT = 100; private final List<Node> controlNodes = new ArrayList<>(); private final List<Node> bodyNodes = new ArrayList<>(); private final List<Node> savedControls = new ArrayList<>(); private final List<Node> savedBody = new ArrayList<>(); private Optional<SlideHiddenListener> slideHiddenListener = Optional.empty(); private final Pane parentControls; private final Pane parentBody; public Slide(Pane parentControls, Pane parentBody) { this.parentControls = parentControls; this.parentBody = parentBody; final ImageView backImage = new ImageView( new Image(Slide.class.getResourceAsStream("/images/back_button.png"), 60.0, 60.0, true, true)); final Button backButton = addSlideControlButton("", (Event) -> hide()); backButton.setGraphic(backImage); } public void showControls() { // If we have less than the maximum number of control buttons // add empty panes as place holders for missing buttons to // ensure control button alignment and size is maintained. if (controlNodes.size() < MAX_CONTROL_BUTTONS) { final int sizeDelta = MAX_CONTROL_BUTTONS - controlNodes.size(); for (int i = 0; i < sizeDelta; i++) { final Pane placeHolderPane = new Pane(); placeHolderPane.setPrefSize(CONTROL_BUTTON_WIDTH, CONTROL_BUTTON_HEIGHT); controlNodes.add(placeHolderPane); } } show(parentControls, controlNodes, savedControls); } public void showBody() { show(parentBody, bodyNodes, savedBody); } public void hide() { hide(parentBody, bodyNodes, savedBody); hide(parentControls, controlNodes, savedControls); // Assumption that body will never show without the controls if (slideHiddenListener.isPresent()) slideHiddenListener.get().onSlideHidden(); } private void show(Pane parentContainer, List<Node> slideList, List<Node> savedList) { // Do not show twice if (!savedList.isEmpty()) return; savedList.addAll(parentContainer.getChildren()); parentContainer.getChildren().setAll(slideList); } private void hide(Pane parentContainer, List<Node> slideList, List<Node> savedList) { parentContainer.getChildren().removeAll(slideList); parentContainer.getChildren().addAll(savedList); savedList.clear(); } public void setOnSlideHidden(SlideHiddenListener slideHiddenListener) { this.slideHiddenListener = Optional.ofNullable(slideHiddenListener); } // This used to add the buttons that appear across the very top row // of the slide. These are intended to control the content // that appears on the rest of the slide protected Button addSlideControlButton(String text, final EventHandler<ActionEvent> eventHandler) { if (controlNodes.size() >= MAX_CONTROL_BUTTONS) { throw new AssertionError("The slide already has the maximum number of control buttons"); } final Button controlButton = new Button(text); controlButton.setPrefSize(CONTROL_BUTTON_WIDTH, CONTROL_BUTTON_HEIGHT); controlButton.setOnAction(eventHandler); controlNodes.add(controlButton); return controlButton; } protected void addBodyNode(Node node) { bodyNodes.add(node); } }