291 lines
8.9 KiB
Haxe
291 lines
8.9 KiB
Haxe
package funkin.editors.charter;
|
|
|
|
import flixel.group.FlxGroup;
|
|
import flixel.util.FlxColor;
|
|
import funkin.backend.chart.ChartData.ChartEvent;
|
|
import funkin.backend.chart.EventsData;
|
|
import funkin.backend.scripting.DummyScript;
|
|
import funkin.backend.scripting.Script;
|
|
import funkin.backend.system.Conductor;
|
|
import funkin.editors.charter.CharterEvent.EventNumber;
|
|
|
|
using StringTools;
|
|
|
|
class CharterEventScreen extends UISubstateWindow {
|
|
//public var cam:FlxCamera;
|
|
public var chartEvent:CharterEvent;
|
|
|
|
public var step:Float = 0;
|
|
public var events:Array<ChartEvent> = [];
|
|
public var eventsList:UIButtonList<EventButton>;
|
|
|
|
public var eventName:UIText;
|
|
|
|
public var paramsPanel:FlxGroup;
|
|
public var paramsFields:Array<FlxBasic> = [];
|
|
|
|
public var saveButton:UIButton;
|
|
public var closeButton:UIButton;
|
|
|
|
public function new(step:Float, ?chartEvent:Null<CharterEvent>) {
|
|
if (chartEvent != null) this.chartEvent = chartEvent;
|
|
this.step = step;
|
|
super();
|
|
}
|
|
|
|
public override function create() {
|
|
var creatingEvent:Bool = chartEvent == null;
|
|
if (creatingEvent) chartEvent = new CharterEvent(step, []);
|
|
|
|
winTitle = creatingEvent ? "Create Event Group" : "Edit Event Group";
|
|
winWidth = 960;
|
|
|
|
super.create();
|
|
|
|
FlxG.sound.music.pause(); // prevent the song from continuing
|
|
Charter.instance.vocals.pause();
|
|
for (strumLine in Charter.instance.strumLines.members) strumLine.vocals.pause();
|
|
|
|
events = chartEvent.events.copy();
|
|
|
|
eventsList = new UIButtonList<EventButton>(0,0,75, 570, "", FlxPoint.get(73, 40), null, 0);
|
|
eventsList.drawTop = false;
|
|
eventsList.addButton.callback = () -> openSubState(new CharterEventTypeSelection(function(eventName) {
|
|
events.push({
|
|
time: Conductor.getTimeForStep(chartEvent.step),
|
|
params: [],
|
|
name: eventName
|
|
});
|
|
eventsList.add(new EventButton(events[events.length-1], CharterEvent.generateEventIcon(events[events.length-1]), events.length-1, this, eventsList));
|
|
changeTab(events.length-1);
|
|
}, chartEvent.step));
|
|
for (k=>i in events)
|
|
eventsList.add(new EventButton(i, CharterEvent.generateEventIcon(i), k, this, eventsList));
|
|
add(eventsList);
|
|
|
|
paramsPanel = new FlxGroup();
|
|
add(paramsPanel);
|
|
|
|
saveButton = new UIButton(windowSpr.x + windowSpr.bWidth - 20, windowSpr.y + windowSpr.bHeight - 16 - 32, "Save & Close", function() {
|
|
saveCurTab();
|
|
chartEvent.refreshEventIcons();
|
|
|
|
if (events.length <= 0 && !creatingEvent)
|
|
Charter.instance.deleteSelection([chartEvent]);
|
|
else if (events.length > 0) {
|
|
var oldEvents:Array<ChartEvent> = chartEvent.events.copy();
|
|
chartEvent.events = [
|
|
for (i in eventsList.buttons.members) i.event
|
|
];
|
|
|
|
if (creatingEvent && events.length > 0)
|
|
Charter.instance.createSelection([chartEvent]);
|
|
else {
|
|
chartEvent.events = [for (i in eventsList.buttons.members) i.event];
|
|
chartEvent.refreshEventIcons();
|
|
|
|
Charter.undos.addToUndo(CEditEvent(chartEvent, oldEvents, [for (event in events) Reflect.copy(event)]));
|
|
}
|
|
}
|
|
|
|
Charter.instance.updateBPMEvents();
|
|
close();
|
|
});
|
|
saveButton.x -= saveButton.bWidth;
|
|
add(saveButton);
|
|
|
|
closeButton = new UIButton(saveButton.x - 10, saveButton.y, "Close", ()->close());
|
|
closeButton.color = 0xFFFF0000;
|
|
closeButton.x -= closeButton.bWidth;
|
|
add(closeButton);
|
|
|
|
eventName = new UIText(eventsList.bWidth + windowSpr.x + 15, windowSpr.y + 41, 0, "", 24);
|
|
add(eventName);
|
|
|
|
changeTab(0);
|
|
}
|
|
|
|
public var curEvent:Int = -1;
|
|
|
|
public function changeTab(id:Int, save:Bool = true) {
|
|
if (save)
|
|
saveCurTab();
|
|
|
|
// destroy old elements
|
|
paramsFields = [];
|
|
while(paramsPanel.members.length > 0) {
|
|
var e = paramsPanel.members.pop();
|
|
if(e != null) {
|
|
e.destroy();
|
|
}
|
|
}
|
|
|
|
if (id >= 0 && id < events.length) {
|
|
curEvent = id;
|
|
var curEvent = events[curEvent];
|
|
eventName.text = curEvent.name;
|
|
|
|
generateEventUI(curEvent);
|
|
} else {
|
|
eventName.text = "No event";
|
|
curEvent = -1;
|
|
}
|
|
}
|
|
|
|
function generateEventUI(event:ChartEvent):Void {
|
|
var script = CharterEvent.getUIScript(event, "event-ui");
|
|
if(script != null && !(script is DummyScript)) {
|
|
script.set("paramsPanel", paramsPanel);
|
|
script.set("paramsFields", paramsFields);
|
|
if(script.get("generateUI") != null) {
|
|
if(script.call("generateUI") == false)
|
|
return;
|
|
}
|
|
}
|
|
|
|
// add new elements
|
|
var _y:Float = eventName.y + eventName.height + 10;
|
|
var params = EventsData.getEventParams(event.name);
|
|
for(k=>param in params) {
|
|
var x = eventName.x + (param.x == null ? 0 : param.x);
|
|
var y = (param.y == null ? _y : param.y);
|
|
|
|
function addLabel() {
|
|
var label:UIText = new UIText(x, y, 0, param.name);
|
|
_y += label.height + 4;
|
|
y += label.height + 4;
|
|
paramsPanel.add(label);
|
|
};
|
|
|
|
var value:Dynamic = CoolUtil.getDefault(event.params[k], param.defValue);
|
|
var lastAdded = switch(param.type) {
|
|
case TString:
|
|
addLabel();
|
|
var textBox:UITextBox = new UITextBox(x, y, cast value);
|
|
paramsPanel.add(textBox); paramsFields.push(textBox);
|
|
textBox;
|
|
case TBool:
|
|
var checkbox = new UICheckbox(x, y, param.name, cast value);
|
|
paramsPanel.add(checkbox); paramsFields.push(checkbox);
|
|
checkbox;
|
|
case TInt(min, max, step):
|
|
addLabel();
|
|
var numericStepper = new UINumericStepper(x, y, cast value, CoolUtil.getDefault(step, 1), 0, min, max);
|
|
paramsPanel.add(numericStepper); paramsFields.push(numericStepper);
|
|
numericStepper;
|
|
case TFloat(min, max, step, precision):
|
|
addLabel();
|
|
var numericStepper = new UINumericStepper(x, y, cast value, CoolUtil.getDefault(step, 1), precision, min, max);
|
|
paramsPanel.add(numericStepper); paramsFields.push(numericStepper);
|
|
numericStepper;
|
|
case TStrumLine:
|
|
addLabel();
|
|
var dropdown = new UIDropDown(x, y, 320, 32, [
|
|
for(k=>s in cast(FlxG.state, Charter).strumLines.members)
|
|
'Strumline #${k+1} (${s.strumLine.characters[0]})'
|
|
], cast value);
|
|
paramsPanel.add(dropdown); paramsFields.push(dropdown);
|
|
dropdown;
|
|
case TColorWheel:
|
|
addLabel();
|
|
var colorWheel = new UIColorwheel(x, y, CoolUtil.getColorFromDynamic(value));
|
|
paramsPanel.add(colorWheel); paramsFields.push(colorWheel);
|
|
colorWheel;
|
|
case TDropDown(options):
|
|
addLabel();
|
|
var dropdown = new UIDropDown(x, y, 320, 32, options, Std.int(Math.abs(options.indexOf(cast value))));
|
|
paramsPanel.add(dropdown); paramsFields.push(dropdown);
|
|
dropdown;
|
|
default:
|
|
paramsFields.push(null);
|
|
null;
|
|
}
|
|
if (lastAdded is UISliceSprite)
|
|
_y += cast(lastAdded, UISliceSprite).bHeight + 4;
|
|
else if (lastAdded is FlxSprite)
|
|
_y += cast(lastAdded, FlxSprite).height + 6;
|
|
}
|
|
|
|
if(script != null && !(script is DummyScript)) {
|
|
if(script.get("postGenerateUI") != null) {
|
|
script.set("params", params);
|
|
script.call("postGenerateUI");
|
|
}
|
|
}
|
|
}
|
|
|
|
public function saveCurTab() {
|
|
if (curEvent < 0) return;
|
|
|
|
var dataParams = EventsData.getEventParams(events[curEvent].name);
|
|
events[curEvent].params = [
|
|
for(i=>p in paramsFields) {
|
|
if (p is UIDropDown) {
|
|
if (dataParams[i].type == TStrumLine) cast(p, UIDropDown).index;
|
|
else cast(p, UIDropDown).label.text;
|
|
}
|
|
else if (p is UINumericStepper) {
|
|
var stepper = cast(p, UINumericStepper);
|
|
@:privateAccess stepper.__onChange(stepper.label.text);
|
|
if (stepper.precision == 0) // int
|
|
Std.int(stepper.value);
|
|
else
|
|
stepper.value;
|
|
}
|
|
else if (p is UITextBox)
|
|
cast(p, UITextBox).label.text;
|
|
else if (p is UICheckbox)
|
|
cast(p, UICheckbox).checked;
|
|
else if (p is UIColorwheel)
|
|
cast(p, UIColorwheel).curColor;
|
|
else
|
|
null;
|
|
}
|
|
];
|
|
}
|
|
}
|
|
|
|
class EventButton extends UIButton {
|
|
public var icon:FlxSprite = null;
|
|
public var event:ChartEvent = null;
|
|
public var deleteButton:UIButton;
|
|
public var deleteIcon:FlxSprite;
|
|
|
|
public function new(event:ChartEvent, icon:FlxSprite, id:Int, substate:CharterEventScreen, parent:UIButtonList<EventButton>) {
|
|
this.icon = icon;
|
|
this.event = event;
|
|
super(0,0,"" ,function() {
|
|
substate.changeTab(id);
|
|
for(i in parent.buttons.members)
|
|
i.alpha = i == this ? 1 : 0.25;
|
|
},73,40);
|
|
autoAlpha = false;
|
|
|
|
members.push(icon);
|
|
icon.setPosition(18 - icon.width / 2, 20 - icon.height / 2);
|
|
|
|
deleteButton = new UIButton(bWidth - 30, y + (bHeight - 26) / 2, "", function () {
|
|
substate.events.splice(id, 1);
|
|
substate.changeTab(id, false);
|
|
parent.remove(this);
|
|
}, 26, 26);
|
|
deleteButton.color = FlxColor.RED;
|
|
deleteButton.autoAlpha = false;
|
|
members.push(deleteButton);
|
|
|
|
deleteIcon = new FlxSprite(deleteButton.x + (15/2), deleteButton.y + 4).loadGraphic(Paths.image('editors/delete-button'));
|
|
deleteIcon.antialiasing = false;
|
|
members.push(deleteIcon);
|
|
}
|
|
|
|
override function update(elapsed) {
|
|
super.update(elapsed);
|
|
|
|
deleteButton.selectable = selectable;
|
|
deleteButton.shouldPress = shouldPress;
|
|
|
|
icon.setPosition(x + (18 - icon.width / 2),y + (20 - icon.height / 2));
|
|
deleteButton.setPosition(x + (bWidth - 30), y + (bHeight - 26) / 2);
|
|
deleteIcon.setPosition(deleteButton.x + (10/2), deleteButton.y + 4);
|
|
}
|
|
} |