Java tutorial
/* * 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); } } }