/* * Copyright 2016 Nathan Howard * * This file is part of OpenGrave * * OpenGrave 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. * * OpenGrave 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 OpenGrave. If not, see <http://www.gnu.org/licenses/>. */ package com.opengrave.og.states; import java.util.ArrayList; import java.util.Collections; import com.opengrave.common.MenuInfo; import com.opengrave.common.PopupMenuOption; import com.opengrave.common.event.EventDispatcher; import com.opengrave.common.event.EventHandler; import com.opengrave.common.event.EventHandlerPriority; import com.opengrave.common.event.EventListener; import com.opengrave.og.MainThread; import com.opengrave.og.gui.*; import com.opengrave.og.gui.callback.PopupOptionChosen; import com.opengrave.og.input.*; import com.opengrave.og.resources.GUIXML; import com.opengrave.og.util.Vector4f; public class BindingState extends BaseState implements EventListener { int index = 0; private ScrollBox sb; private VerticalContainer vert; ArrayList<ControlBinding> cbList = new ArrayList<ControlBinding>(); boolean movingUp = false, movingDown = false; boolean waitingPad = false, waitingKey = false, waitingMouse = false; private MenuInfo bindMenu; public BindingState() { EventDispatcher.addHandler(this); GUIXML mainMenuFile = new GUIXML("gui/bind.xml"); screen = mainMenuFile.getGUI(); sb = (ScrollBox) screen.getElementById("scroll"); vert = (VerticalContainer) screen.getElementById("list"); bindMenu = new MenuInfo(); bindMenu.addOptions("main", new PopupMenuOption("keyopt", "none", "Keyboard"), new PopupMenuOption("mouseopt", "none", "Mouse Button"), new PopupMenuOption("padopt", "none", "Gamepad")); populateList(); } private void populateList() { vert.removeAllChildren(); cbList.clear(); synchronized (InputMain.bindings) { cbList.addAll(InputMain.bindings); } Collections.sort(cbList); vert.getElementData().minimum_width = 300; vert.getElementData().maximum_width = 300; for (ControlBinding cb : cbList) { ElementData ed = new ElementData(vert.getElementData()); ed.maximum_height = 32; ed.minimum_height = 32; ed.maximum_width = 500; ed.minimum_width = 500; HorizontalContainer hz = new HorizontalContainer(ed); ed = new ElementData(vert.getElementData()); ed.maximum_height = 32; ed.maximum_width = 256; TextArea ta = new TextArea(ed); ta.setString(cb.getControlName()); hz.addChildEnd(ta); hz.drawBackground(true); for (InputBinding ib : cb.getList()) { if (ib instanceof PadBinding) { PadBinding pb = (PadBinding) ib; if (InputMain.cl == null || !pb.getPadName().equalsIgnoreCase(InputMain.cl.getName())) { continue; } } ed = new ElementData(vert.getElementData()); ImageInput ii = new ImageInput(ed); ii.set(ib); hz.addChildEnd(ii); } vert.addChildEnd(hz); } highlight(); } @EventHandler(priority = EventHandlerPriority.EARLY) public void onKeyPress(KeyboardRawPressEvent event) { if (!isActive()) { return; } if (!waitingKey) { return; } waitingKey = false; ControlBinding cb = cbList.get(index); cb.addInput(new KeyBinding(event.getKey())); event.setConsumed(); screen.closePopup(); populateList(); } @EventHandler(priority = EventHandlerPriority.EARLY) public void onPadPress(JoystickRawChangeEvent event) { // Because it's a raw, alot of helper functions will be needed. Oh well if (event.isConsumed() || !isActive() || !waitingPad || InputMain.cl == null) { return; } if (event.getState()) { event.setConsumed(); ControlBinding cb = cbList.get(index); cb.addInput(new PadBinding(InputMain.cl.getName(), event.getAxis())); waitingPad = false; screen.closePopup(); populateList(); } } @EventHandler(priority = EventHandlerPriority.LATE) public void onInputCaptured(InputChangeEvent event) { if (!isActive() || !event.getState() || event.isConsumed()) { return; } if (waitingPad || waitingMouse || waitingKey) { return; } int inc = 0; if (event.getControl().getControlName().equalsIgnoreCase("move_y_positive")) { if (event.getRawState() < 0f) { inc = -1; } else { inc = 1; } event.isConsumed(); } else if (event.getControl().getControlName().equalsIgnoreCase("move_y_negative")) { if (event.getRawState() < 0f) { inc = 1; } else { inc = -1; } event.isConsumed(); } else if (event.getControl().getControlName().equalsIgnoreCase("menu_1")) { if (screen.hasPopup()) { return; } event.setConsumed(); PopupMenu pm = new PopupMenu(new ElementData()); pm.setMenuOptions("main", 0, bindMenu, MainThread.lastW / 2, MainThread.lastH / 2, this); screen.showPopup(pm); return; } else if (event.getControl().getControlName().equalsIgnoreCase("menu_2")) { if (screen.hasPopup()) { return; } event.setConsumed(); ControlBinding cb = cbList.get(index); cb.removeInput(null); populateList(); return; } else if (event.getControl().getControlName().equalsIgnoreCase("menu_cancel")) { MainThread.changeState(new MenuState()); } else if (event.getControl().getControlName().equalsIgnoreCase("menu_next")) { // Save System.out.println("Saved bindings"); InputMain.saveCustomBindings(); } undoHighlight(); index += inc; if (index < 0) { index = cbList.size() - 1; } if (index >= cbList.size()) { index = 0; } highlight(); } private void highlight() { UIElement a = vert.getChildren().get(index); Vector4f ac = screen.getElementData().activeColour; a.getElementData().defaultColour = new Vector4f(ac.x, ac.y, ac.z, ac.w); sb.scrollTo(a); } private void undoHighlight() { UIElement a = vert.getChildren().get(index); Vector4f dc = screen.getElementData().defaultColour; a.getElementData().defaultColour = new Vector4f(dc.x, dc.y, dc.z, dc.w); } // TODO This. All of this. // List out all bindings from InputMain.bindings (SYNC) // Allow alteration and removal of InputBindings for each ControlBinding // Allow insertion of new ControlBinding // Allow insertion of InputBinding to any ControlBinding @Override public void start() { } @Override public void stop() { } @Override public void update(float delta) { } @EventHandler(priority = EventHandlerPriority.EARLY) public void onMenuChosen(PopupOptionChosen event) { if (!isActive()) { return; } if (event.getId().equalsIgnoreCase("keyopt")) { TextArea ta = new TextArea(new ElementData(screen.getElementData())); ta.setString("Please press a keyboard key to bind to this action"); UIPopup popup = new UIPopup(new ElementData(screen.getElementData())); ta.getElementData().minimum_width = 10; ta.drawBackground(true); popup.addChildEnd(ta); popup.setPosition(MainThread.lastW / 2, MainThread.lastH / 2); screen.showPopup(popup); waitingKey = true; } else if (event.getId().equalsIgnoreCase("padopt")) { TextArea ta = new TextArea(new ElementData(screen.getElementData())); ta.setString("Press the pad button, stick or trigger to bind to this action "); UIPopup popup = new UIPopup(new ElementData(screen.getElementData())); ta.drawBackground(true); popup.addChildEnd(ta); popup.setPosition(MainThread.lastW / 2, MainThread.lastH / 2); screen.showPopup(popup); waitingPad = true; } else if (event.getId().equalsIgnoreCase("mouseopt")) { TextArea ta = new TextArea(new ElementData(screen.getElementData())); UIPopup popup = new UIPopup(new ElementData(screen.getElementData())); ta.setString("Please press the mouse button to bind to this action"); ta.drawBackground(true); popup.addChildEnd(ta); popup.setPosition(MainThread.lastW / 2, MainThread.lastH / 2); screen.showPopup(popup); waitingMouse = true; } } }