package de.golfgl.gdx.controllers; import com.badlogic.gdx.scenes.scene2d.Action; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.scenes.scene2d.ui.Button; import com.badlogic.gdx.scenes.scene2d.ui.Dialog; import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.utils.Array; /** * ControllerMenuDialog extends libGDX' {@link Dialog}. Use {@link #addFocusableActor(Actor)} to safely add * Actors to the Stage's focusable actors list. If you use {@link #button(Button, Object)}, it will be called * automatically. * <p> * Created by Benjamin Schulte on 04.11.2017. */ public class ControllerMenuDialog extends Dialog { protected Array<Actor> buttonsToAdd = new Array<>(); protected Actor previousFocusedActor; protected Actor previousEscapeActor; public ControllerMenuDialog(String title, Skin skin) { super(title, skin); } public ControllerMenuDialog(String title, Skin skin, String windowStyleName) { super(title, skin, windowStyleName); } public ControllerMenuDialog(String title, WindowStyle windowStyle) { super(title, windowStyle); } @Override public Dialog button(Button button, Object object) { addFocusableActor(button); if (getStage() != null && getStage() instanceof ControllerMenuStage) ((ControllerMenuStage) getStage()).addFocusableActor(button); return super.button(button, object); } @Override protected void setStage(Stage stage) { if (stage == null && getStage() != null && getStage() instanceof ControllerMenuStage) { ((ControllerMenuStage) getStage()).removeFocusableActors(buttonsToAdd); } super.setStage(stage); if (stage != null && stage instanceof ControllerMenuStage) { ((ControllerMenuStage) stage).addFocusableActors(buttonsToAdd); } } @Override public Dialog show(Stage stage, Action action) { previousFocusedActor = null; previousEscapeActor = null; super.show(stage, action); if (stage instanceof ControllerMenuStage) { previousFocusedActor = ((ControllerMenuStage) stage).getFocusedActor(); previousEscapeActor = ((ControllerMenuStage) stage).getEscapeActor(); ((ControllerMenuStage) stage).setFocusedActor(getConfiguredDefaultActor()); ((ControllerMenuStage) stage).setEscapeActor(getConfiguredEscapeActor()); } return this; } /** * @return Actor that should get the focus when the dialog is shown */ protected Actor getConfiguredDefaultActor() { return buttonsToAdd.size >= 1 ? buttonsToAdd.get(0) : null; } /** * @return Actor that should take Action when the escape button is hit while the dialog is shown */ protected Actor getConfiguredEscapeActor() { return buttonsToAdd.size == 1 ? buttonsToAdd.get(0) : null; } @Override public void hide(Action action) { if (getStage() != null && getStage() instanceof ControllerMenuStage) { Actor currentFocusedActor = ((ControllerMenuStage) getStage()).getFocusedActor(); if (previousFocusedActor != null && previousFocusedActor.getStage() == getStage() && (currentFocusedActor == null || !currentFocusedActor.hasParent() || currentFocusedActor.isDescendantOf(this))) ((ControllerMenuStage) getStage()).setFocusedActor(previousFocusedActor); Actor currentEscapeActor = ((ControllerMenuStage) getStage()).getEscapeActor(); if (previousEscapeActor != null && previousEscapeActor.getStage() == getStage() && (currentEscapeActor == null || !currentEscapeActor.hasParent() || currentEscapeActor.isDescendantOf(this))) ((ControllerMenuStage) getStage()).setEscapeActor(previousEscapeActor); } super.hide(action); } /** * Call this for every actor that can be focused by keys. The actors will be added to the Stage's focusable * actors when the dialog is added to a Stage, and removed from Stage's focusable Actors when the dialog is removed * from the stage. * * @param actor */ public void addFocusableActor(Actor actor) { buttonsToAdd.add(actor); if (getStage() != null && getStage() instanceof ControllerMenuStage) ((ControllerMenuStage) getStage()).addFocusableActor(actor); } }