Funkin/source/ui/ControlsMenu.hx

212 lines
5.4 KiB
Haxe
Raw Normal View History

2021-02-23 19:59:36 -05:00
package ui;
2021-03-16 10:56:08 -04:00
import ui.MenuList;
2021-02-23 19:59:36 -05:00
import flixel.FlxG;
import flixel.FlxCamera;
import flixel.FlxObject;
import flixel.FlxSprite;
import flixel.group.FlxGroup;
import flixel.input.keyboard.FlxKey;
import Controls;
import ui.AtlasText;
import ui.TextMenuList;
2021-03-13 21:11:56 -05:00
class ControlsMenu extends ui.OptionsState.Page
2021-02-23 19:59:36 -05:00
{
2021-03-16 10:56:08 -04:00
static var controlList = Control.createAll();
/*
* Defines groups of controls that cannot share inputs, like left and right. Say, if ACCEPT is Z, Back is X,
* if the player sets Back to Z it also set ACCEPT to X. This prevents the player from setting the controls in
* a way the prevents them from changing more controls or exiting the menu.
*/
static var controlGroups:Array<Array<Control>> =
[ [ NOTE_UP, NOTE_DOWN, NOTE_LEFT, NOTE_RIGHT ]
, [ UI_UP, UI_DOWN, UI_LEFT, UI_RIGHT, ACCEPT, BACK ]
];
var itemGroups:Array<Array<InputItem>> = [for (i in 0...controlGroups.length) []];
var controlGrid:MenuTypedList<InputItem>;
2021-03-13 21:11:56 -05:00
var labels:FlxTypedGroup<AtlasText>;
var menuCamera:FlxCamera;
2021-03-16 10:56:08 -04:00
var prompt:Prompt;
2021-03-13 21:11:56 -05:00
public function new()
{
super();
menuCamera = new FlxCamera();
FlxG.cameras.add(menuCamera);// false);
if (FlxCamera.defaultCameras.indexOf(menuCamera) != -1)
{
FlxCamera.defaultCameras = FlxCamera.defaultCameras.copy();
FlxCamera.defaultCameras.remove(menuCamera);
}
menuCamera.bgColor = 0x0;
2021-03-16 10:56:08 -04:00
camera = menuCamera;
2021-03-13 21:11:56 -05:00
add(labels = new FlxTypedGroup<AtlasText>());
2021-03-16 10:56:08 -04:00
add(controlGrid = new MenuTypedList(Columns(2)));
2021-03-13 21:11:56 -05:00
// FlxG.debugger.drawDebug = true;
2021-03-16 10:56:08 -04:00
var y = 30;
var spacer = 70;
var currentHeader:String = null;
// list order is determined by enum order
2021-03-13 21:11:56 -05:00
for (i in 0...controlList.length)
{
var control = controlList[i];
var name = control.getName();
2021-03-16 10:56:08 -04:00
if (currentHeader != "UI_" && name.indexOf("UI_") == 0)
{
currentHeader = "UI_";
labels.add(new BoldText(0, y, "UI")).screenCenter(X);
y += spacer;
}
else if (currentHeader != "NOTE_" && name.indexOf("NOTE_") == 0)
{
currentHeader = "NOTE_";
labels.add(new BoldText(0, y, "NOTES")).screenCenter(X);
y += spacer;
}
if (currentHeader != null && name.indexOf(currentHeader) == 0)
name = name.substr(currentHeader.length);
var label = labels.add(new BoldText(250, y, name));
2021-03-13 21:11:56 -05:00
createItem(label.x + 400, y, control, 0);
createItem(label.x + 600, y, control, 1);
2021-03-16 10:56:08 -04:00
y += spacer;
2021-03-13 21:11:56 -05:00
}
2021-03-16 10:56:08 -04:00
trace(itemGroups.map((group)->group.map((item)->item.label.text)));
2021-03-13 21:11:56 -05:00
var selected = controlGrid.members[0];
var camFollow = new FlxObject(FlxG.width / 2, selected.y, 70, 70);
menuCamera.follow(camFollow, null, 0.06);
var margin = 100;
menuCamera.deadzone.set(0, margin, menuCamera.width, menuCamera.height - margin * 2);
controlGrid.onChange.add(function (selected) camFollow.y = selected.y);
2021-03-16 10:56:08 -04:00
prompt = new Prompt("Press any key to rebind\n\n\n\n Escape to cancel", None);
prompt.create();
prompt.createBgFromMargin();
prompt.back.scrollFactor.set(0, 0);
prompt.exists = false;
add(prompt);
2021-03-13 21:11:56 -05:00
}
function createItem(x = 0.0, y = 0.0, control:Control, index:Int)
{
2021-03-16 10:56:08 -04:00
var item = new InputItem(x, y, control, index, onSelect);
for (i in 0...controlGroups.length)
2021-03-13 21:11:56 -05:00
{
2021-03-16 10:56:08 -04:00
if (controlGroups[i].contains(control))
itemGroups[i].push(item);
2021-03-13 21:11:56 -05:00
}
2021-03-16 10:56:08 -04:00
return controlGrid.addItem(item.name, item);
2021-03-13 21:11:56 -05:00
}
2021-03-16 10:56:08 -04:00
function onSelect():Void
2021-03-13 21:11:56 -05:00
{
controlGrid.enabled = false;
2021-03-16 10:56:08 -04:00
canExit = false;
prompt.exists = true;
}
override function update(elapsed:Float)
{
super.update(elapsed);
if (prompt.exists)
{
var key = FlxG.keys.firstJustPressed();
if (key != NONE)
{
if (key != ESCAPE)
onKeySelect(key);
closePrompt();
}
}
}
function onKeySelect(key:Int)
{
var item = controlGrid.selectedItem;
for (group in itemGroups)
{
if (group.contains(item))
{
for (otherItem in group)
{
// Check if items in the same group have the new input
if (otherItem != item && otherItem.input == key)
{
// replace that input with this items old input.
PlayerSettings.player1.controls.replaceBinding(otherItem.control, Keys, item.input, otherItem.input);
// Don't use resetItem() since items share names/labels
otherItem.input = item.input;
otherItem.label.text = item.label.text;
}
}
}
}
PlayerSettings.player1.controls.replaceBinding(item.control, Keys, key, item.input);
// Don't use resetItem() since items share names/labels
item.input = key;
item.label.text = item.getLabel(key);
}
function closePrompt()
{
controlGrid.enabled = true;
canExit = true;
prompt.exists = false;
}
override function destroy()
{
super.destroy();
if (FlxG.cameras.list.contains(menuCamera))
FlxG.cameras.remove(menuCamera);
2021-03-13 21:11:56 -05:00
}
override function set_enabled(value:Bool)
{
controlGrid.enabled = value;
return super.set_enabled(value);
}
2021-03-16 10:56:08 -04:00
}
class InputItem extends TextMenuItem
{
public var control:Control;
public var input:Int = -1;
public function new (x = 0.0, y = 0.0, control, index, ?callback)
{
this.control = control;
var list = PlayerSettings.player1.controls.getInputsFor(control, Keys);
if (list.length > index)
{
if (list[index] != FlxKey.ESCAPE)
input = list[index];
else if (list.length > 2)
// Escape isn't mappable, show a third option, instead.
input = list[2];
}
;
super(x, y, getLabel(input), Default, callback);
}
public function getLabel(input:Int)
{
return input == -1 ? "---" : InputFormatter.format(input, Keys);
}
2021-02-23 19:59:36 -05:00
}