de.cubicvoxel.openspacebox.ingame.ui.hud.Menu.java Source code

Java tutorial

Introduction

Here is the source code for de.cubicvoxel.openspacebox.ingame.ui.hud.Menu.java

Source

/*
 * This file is part of OpenSpaceBox.
 * Copyright (C) 2018 by Maik Becker <hi@maik.codes>
 *
 * OpenSpaceBox 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.
 *
 * OpenSpaceBox 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 OpenSpaceBox.  If not, see <http://www.gnu.org/licenses/>.
 */

package de.cubicvoxel.openspacebox.ingame.ui.hud;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.utils.Align;
import de.cubicvoxel.openspacebox.OpenSpaceBox;
import de.cubicvoxel.openspacebox.assetmanagement.asset.FA;
import de.cubicvoxel.openspacebox.assetmanagement.asset.FontAsset;
import de.cubicvoxel.openspacebox.assetmanagement.asset.ResourceBundles;
import de.cubicvoxel.openspacebox.assetmanagement.asset.TextureAsset;
import de.cubicvoxel.openspacebox.ingame.controller.GameControllers;
import de.cubicvoxel.openspacebox.ingame.ui.logbook.PlayerLogBook;
import de.cubicvoxel.openspacebox.util.UpdateMultiplexer;
import de.cubicvoxel.openspacebox.util.animation.Anim;
import de.cubicvoxel.openspacebox.util.animation.Easing;
import de.cubicvoxel.openspacebox.util.widget.OsbGui;
import de.cubicvoxel.openspacebox.util.widget.OsbTextButton;

/**
 * @author Maik Becker {@literal <hi@maik.codes>}
 */
public class Menu extends VerticalGroup {
    public static final float BUTTON_SIZE = Math.min(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()) / 7.0f;
    private static final int SPACING = 20;

    private final UpdateMultiplexer updateMultiplexer = new UpdateMultiplexer();

    private final OsbTextButton openCloseMenuButton;
    private final VerticalGroup menuItemsGroup;
    private final OsbTextButton logMenuButton;
    private final OsbTextButton debugMenuButton;
    private final OsbGui stage;
    private final GameControllers gameControllers;
    private final ResourceBundles resourceBundles;

    public Menu(OsbGui stage, GameControllers gameControllers, ResourceBundles resourceBundles) {
        this.stage = stage;
        this.gameControllers = gameControllers;
        this.resourceBundles = resourceBundles;

        space(SPACING);
        setWidth(BUTTON_SIZE);
        align(Align.top);

        openCloseMenuButton = new OsbTextButton(FA.BARS.asString(), new MenuButtonStyle());
        openCloseMenuButton.setSize(BUTTON_SIZE, BUTTON_SIZE);
        openCloseMenuButton.addListener(new ChangeListener() {
            @Override
            public void changed(ChangeEvent event, Actor actor) {
                if (isOpened())
                    closeMenu();
                else
                    openMenu();
            }
        });
        addActor(openCloseMenuButton);

        menuItemsGroup = new VerticalGroup();
        menuItemsGroup.space(SPACING);
        menuItemsGroup.columnTop();

        logMenuButton = new OsbTextButton(FA.BOOK.asString(), new MenuButtonStyle());
        logMenuButton.setSize(BUTTON_SIZE, BUTTON_SIZE);
        logMenuButton.addListener(new ChangeListener() {
            @Override
            public void changed(ChangeEvent event, Actor actor) {
                final PlayerLogBook playerLogBook = new PlayerLogBook(Menu.this.resourceBundles,
                        Menu.this.gameControllers, Menu.this.stage);

            }
        });
        menuItemsGroup.addActor(logMenuButton);

        debugMenuButton = new OsbTextButton(FA.BUG.asString(), new MenuButtonStyle());
        debugMenuButton.setSize(BUTTON_SIZE, BUTTON_SIZE);
        menuItemsGroup.addActor(debugMenuButton);
    }

    private boolean isOpened() {
        return getChildren().contains(menuItemsGroup, true);
    }

    private void openMenu() {
        openCloseMenuButton.setText(FA.TIMES_CIRCLE.asString());
        openCloseMenuButton.setColor(Color.GRAY);
        addActor(menuItemsGroup);

        menuItemsGroup.layout();

        final float openCloseButtonYOnMenuItemsGroup = openCloseButtonYOnMenuItemsGroup();

        for (final Actor menuItem : menuItemsGroup.getChildren()) {
            final float menuItemOriginalY = menuItem.getY();
            menuItem.setY(openCloseButtonYOnMenuItemsGroup);

            Anim.on(menuItem).duration(.35f).easing(Easing.CUBIC_OUT)
                    .animatePosition(menuItem.getX(), menuItemOriginalY).using(updateMultiplexer)
                    .finishedListener(menuItemsGroup::invalidate).start();
        }
    }

    private void closeMenu() {
        openCloseMenuButton.setText(FA.BARS.asString());
        openCloseMenuButton.setColor(Color.WHITE);

        final float openCloseButtonYOnMenuItemsGroup = openCloseButtonYOnMenuItemsGroup();

        for (final Actor menuItem : menuItemsGroup.getChildren()) {
            final float menuItemOriginalY = menuItem.getY();

            Anim.on(menuItem).easing(Easing.CUBIC_OUT).duration(.25f)
                    .animatePosition(menuItem.getX(), openCloseButtonYOnMenuItemsGroup()).using(updateMultiplexer)
                    .finishedListener(() -> {
                        menuItem.setY(menuItemOriginalY);
                        removeActor(menuItemsGroup);
                    }).start();
        }

    }

    private float openCloseButtonYOnMenuItemsGroup() {
        Vector2 openButtonLocalCoordinates = new Vector2(openCloseMenuButton.getX(), openCloseMenuButton.getY());
        Vector2 openButtonGlobalCoordinates = openCloseMenuButton.getParent()
                .localToStageCoordinates(openButtonLocalCoordinates);
        Vector2 openButtonItemsGroupLocalCoordinates = menuItemsGroup
                .stageToLocalCoordinates(openButtonGlobalCoordinates);

        return openButtonItemsGroupLocalCoordinates.y;
    }

    @Override
    public void act(float delta) {
        super.act(delta);
        updateMultiplexer.update(delta);
    }

    private static class MenuButtonStyle extends TextButton.TextButtonStyle {
        public MenuButtonStyle() {
            font = OpenSpaceBox.getAsset(FontAsset.FONT_AWESOME_MENU);

            Skin skin = new Skin();
            skin.add("up", OpenSpaceBox.getAsset(TextureAsset.UI_MENU_BUTTON));
            skin.add("down", OpenSpaceBox.getAsset(TextureAsset.UI_MENU_BUTTON));

            up = skin.getDrawable("up");
            up.setMinWidth(BUTTON_SIZE);
            up.setMinHeight(BUTTON_SIZE);

            down = skin.getDrawable("down");
            down.setMinHeight(BUTTON_SIZE);
            down.setMinWidth(BUTTON_SIZE);
        }
    }
}