mirror of
https://github.com/FunkinCrew/Funkin.git
synced 2024-11-30 11:26:53 -05:00
21f44edf1d
* A bunch of smaller syntax tweaks. * New crash handler catches and logs critical errors! * Chart editor now has null safety enabled. * Fix -W build issue. * Actually update hmm.json to use the crash handling branch * Fix issues causing crash handler to trigger
680 lines
24 KiB
Haxe
680 lines
24 KiB
Haxe
package funkin.ui.debug.charting;
|
|
|
|
import haxe.ui.containers.TreeView;
|
|
import haxe.ui.containers.TreeViewNode;
|
|
import funkin.play.character.BaseCharacter.CharacterType;
|
|
import funkin.play.event.SongEvent;
|
|
import funkin.play.event.SongEventData;
|
|
import funkin.play.song.SongData.SongTimeChange;
|
|
import funkin.play.song.SongSerializer;
|
|
import funkin.ui.haxeui.components.CharacterPlayer;
|
|
import haxe.ui.components.Button;
|
|
import haxe.ui.components.CheckBox;
|
|
import haxe.ui.components.DropDown;
|
|
import haxe.ui.components.Label;
|
|
import haxe.ui.components.NumberStepper;
|
|
import haxe.ui.components.Slider;
|
|
import haxe.ui.components.TextField;
|
|
import haxe.ui.containers.Box;
|
|
import haxe.ui.containers.Grid;
|
|
import haxe.ui.containers.Group;
|
|
import haxe.ui.containers.VBox;
|
|
import haxe.ui.containers.Frame;
|
|
import haxe.ui.containers.dialogs.CollapsibleDialog;
|
|
import haxe.ui.containers.dialogs.Dialog.DialogButton;
|
|
import haxe.ui.containers.dialogs.Dialog.DialogEvent;
|
|
import haxe.ui.core.Component;
|
|
import haxe.ui.data.ArrayDataSource;
|
|
import haxe.ui.events.UIEvent;
|
|
|
|
/**
|
|
* Available tools for the chart editor state.
|
|
*/
|
|
enum ChartEditorToolMode
|
|
{
|
|
Select;
|
|
Place;
|
|
}
|
|
|
|
/**
|
|
* Static functions which handle building themed UI elements for a provided ChartEditorState.
|
|
*/
|
|
@:allow(funkin.ui.debug.charting.ChartEditorState)
|
|
class ChartEditorToolboxHandler
|
|
{
|
|
public static function setToolboxState(state:ChartEditorState, id:String, shown:Bool):Void
|
|
{
|
|
if (shown)
|
|
{
|
|
showToolbox(state, id);
|
|
}
|
|
else
|
|
{
|
|
hideToolbox(state, id);
|
|
}
|
|
}
|
|
|
|
public static function showToolbox(state:ChartEditorState, id:String):Void
|
|
{
|
|
var toolbox:CollapsibleDialog = state.activeToolboxes.get(id);
|
|
|
|
if (toolbox == null) toolbox = initToolbox(state, id);
|
|
|
|
if (toolbox != null)
|
|
{
|
|
toolbox.showDialog(false);
|
|
|
|
switch (id)
|
|
{
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_TOOLS_LAYOUT:
|
|
onShowToolboxTools(state, toolbox);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_NOTEDATA_LAYOUT:
|
|
onShowToolboxNoteData(state, toolbox);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_EVENTDATA_LAYOUT:
|
|
onShowToolboxEventData(state, toolbox);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_DIFFICULTY_LAYOUT:
|
|
onShowToolboxDifficulty(state, toolbox);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_METADATA_LAYOUT:
|
|
onShowToolboxMetadata(state, toolbox);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_CHARACTERS_LAYOUT:
|
|
onShowToolboxCharacters(state, toolbox);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT:
|
|
onShowToolboxPlayerPreview(state, toolbox);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT:
|
|
onShowToolboxOpponentPreview(state, toolbox);
|
|
default:
|
|
// This happens if you try to load an unknown layout.
|
|
trace('ChartEditorToolboxHandler.showToolbox() - Unknown toolbox ID: $id');
|
|
}
|
|
}
|
|
else
|
|
{
|
|
trace('ChartEditorToolboxHandler.showToolbox() - Could not retrieve toolbox: $id');
|
|
}
|
|
}
|
|
|
|
public static function hideToolbox(state:ChartEditorState, id:String):Void
|
|
{
|
|
var toolbox:CollapsibleDialog = state.activeToolboxes.get(id);
|
|
|
|
if (toolbox == null) toolbox = initToolbox(state, id);
|
|
|
|
if (toolbox != null)
|
|
{
|
|
toolbox.hideDialog(DialogButton.CANCEL);
|
|
|
|
switch (id)
|
|
{
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_TOOLS_LAYOUT:
|
|
onHideToolboxTools(state, toolbox);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_NOTEDATA_LAYOUT:
|
|
onHideToolboxNoteData(state, toolbox);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_EVENTDATA_LAYOUT:
|
|
onHideToolboxEventData(state, toolbox);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_DIFFICULTY_LAYOUT:
|
|
onHideToolboxDifficulty(state, toolbox);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_METADATA_LAYOUT:
|
|
onHideToolboxMetadata(state, toolbox);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_CHARACTERS_LAYOUT:
|
|
onHideToolboxCharacters(state, toolbox);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT:
|
|
onHideToolboxPlayerPreview(state, toolbox);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT:
|
|
onHideToolboxOpponentPreview(state, toolbox);
|
|
default:
|
|
// This happens if you try to load an unknown layout.
|
|
trace('ChartEditorToolboxHandler.hideToolbox() - Unknown toolbox ID: $id');
|
|
}
|
|
}
|
|
else
|
|
{
|
|
trace('ChartEditorToolboxHandler.hideToolbox() - Could not retrieve toolbox: $id');
|
|
}
|
|
}
|
|
|
|
public static function minimizeToolbox(state:ChartEditorState, id:String):Void
|
|
{
|
|
var toolbox:CollapsibleDialog = state.activeToolboxes.get(id);
|
|
|
|
if (toolbox == null) return;
|
|
|
|
toolbox.minimized = true;
|
|
}
|
|
|
|
public static function maximizeToolbox(state:ChartEditorState, id:String):Void
|
|
{
|
|
var toolbox:CollapsibleDialog = state.activeToolboxes.get(id);
|
|
|
|
if (toolbox == null) return;
|
|
|
|
toolbox.minimized = false;
|
|
}
|
|
|
|
public static function initToolbox(state:ChartEditorState, id:String):CollapsibleDialog
|
|
{
|
|
var toolbox:CollapsibleDialog = null;
|
|
switch (id)
|
|
{
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_TOOLS_LAYOUT:
|
|
toolbox = buildToolboxToolsLayout(state);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_NOTEDATA_LAYOUT:
|
|
toolbox = buildToolboxNoteDataLayout(state);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_EVENTDATA_LAYOUT:
|
|
toolbox = buildToolboxEventDataLayout(state);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_DIFFICULTY_LAYOUT:
|
|
toolbox = buildToolboxDifficultyLayout(state);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_METADATA_LAYOUT:
|
|
toolbox = buildToolboxMetadataLayout(state);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_CHARACTERS_LAYOUT:
|
|
toolbox = buildToolboxCharactersLayout(state);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT:
|
|
toolbox = buildToolboxPlayerPreviewLayout(state);
|
|
case ChartEditorState.CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT:
|
|
toolbox = buildToolboxOpponentPreviewLayout(state);
|
|
default:
|
|
// This happens if you try to load an unknown layout.
|
|
trace('ChartEditorToolboxHandler.initToolbox() - Unknown toolbox ID: $id');
|
|
toolbox = null;
|
|
}
|
|
|
|
// This happens if the layout you try to load has a syntax error.
|
|
if (toolbox == null) return null;
|
|
|
|
// Make sure we can reuse the toolbox later.
|
|
toolbox.destroyOnClose = false;
|
|
state.activeToolboxes.set(id, toolbox);
|
|
|
|
return toolbox;
|
|
}
|
|
|
|
/**
|
|
* Retrieve a toolbox by its layout's asset ID.
|
|
* @param state The ChartEditorState instance.
|
|
* @param id The asset ID of the toolbox layout.
|
|
* @return The toolbox.
|
|
*/
|
|
public static function getToolbox(state:ChartEditorState, id:String):CollapsibleDialog
|
|
{
|
|
var toolbox:CollapsibleDialog = state.activeToolboxes.get(id);
|
|
|
|
// Initialize the toolbox without showing it.
|
|
if (toolbox == null) toolbox = initToolbox(state, id);
|
|
|
|
if (toolbox == null) throw 'ChartEditorToolboxHandler.getToolbox() - Could not retrieve or build toolbox: $id';
|
|
|
|
return toolbox;
|
|
}
|
|
|
|
static function buildToolboxToolsLayout(state:ChartEditorState):CollapsibleDialog
|
|
{
|
|
var toolbox:CollapsibleDialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_TOOLS_LAYOUT);
|
|
|
|
if (toolbox == null) return null;
|
|
|
|
// Starting position.
|
|
toolbox.x = 50;
|
|
toolbox.y = 50;
|
|
|
|
toolbox.onDialogClosed = function(event:DialogEvent) {
|
|
state.setUICheckboxSelected('menubarItemToggleToolboxTools', false);
|
|
}
|
|
|
|
var toolsGroup:Group = toolbox.findComponent('toolboxToolsGroup', Group);
|
|
|
|
if (toolsGroup == null) return null;
|
|
|
|
toolsGroup.onChange = function(event:UIEvent) {
|
|
switch (event.target.id)
|
|
{
|
|
case 'toolboxToolsGroupSelect':
|
|
state.currentToolMode = ChartEditorToolMode.Select;
|
|
case 'toolboxToolsGroupPlace':
|
|
state.currentToolMode = ChartEditorToolMode.Place;
|
|
default:
|
|
trace('ChartEditorToolboxHandler.buildToolboxToolsLayout() - Unknown toolbox tool selected: $event.target.id');
|
|
}
|
|
}
|
|
|
|
return toolbox;
|
|
}
|
|
|
|
static function onShowToolboxTools(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
|
|
|
static function onHideToolboxTools(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
|
|
|
static function buildToolboxNoteDataLayout(state:ChartEditorState):CollapsibleDialog
|
|
{
|
|
var toolbox:CollapsibleDialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_NOTEDATA_LAYOUT);
|
|
|
|
if (toolbox == null) return null;
|
|
|
|
// Starting position.
|
|
toolbox.x = 75;
|
|
toolbox.y = 100;
|
|
|
|
toolbox.onDialogClosed = function(event:DialogEvent) {
|
|
state.setUICheckboxSelected('menubarItemToggleToolboxNotes', false);
|
|
}
|
|
|
|
var toolboxNotesNoteKind:DropDown = toolbox.findComponent('toolboxNotesNoteKind', DropDown);
|
|
var toolboxNotesCustomKindLabel:Label = toolbox.findComponent('toolboxNotesCustomKindLabel', Label);
|
|
var toolboxNotesCustomKind:TextField = toolbox.findComponent('toolboxNotesCustomKind', TextField);
|
|
|
|
toolboxNotesNoteKind.onChange = function(event:UIEvent) {
|
|
var isCustom:Bool = (event.data.id == '~CUSTOM~');
|
|
|
|
if (isCustom)
|
|
{
|
|
toolboxNotesCustomKindLabel.hidden = false;
|
|
toolboxNotesCustomKind.hidden = false;
|
|
|
|
state.selectedNoteKind = toolboxNotesCustomKind.text;
|
|
}
|
|
else
|
|
{
|
|
toolboxNotesCustomKindLabel.hidden = true;
|
|
toolboxNotesCustomKind.hidden = true;
|
|
|
|
state.selectedNoteKind = event.data.id;
|
|
}
|
|
}
|
|
|
|
toolboxNotesCustomKind.onChange = function(event:UIEvent) {
|
|
state.selectedNoteKind = toolboxNotesCustomKind.text;
|
|
}
|
|
|
|
return toolbox;
|
|
}
|
|
|
|
static function onShowToolboxNoteData(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
|
|
|
static function onHideToolboxNoteData(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
|
|
|
static function buildToolboxEventDataLayout(state:ChartEditorState):CollapsibleDialog
|
|
{
|
|
var toolbox:CollapsibleDialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_EVENTDATA_LAYOUT);
|
|
|
|
if (toolbox == null) return null;
|
|
|
|
// Starting position.
|
|
toolbox.x = 100;
|
|
toolbox.y = 150;
|
|
|
|
toolbox.onDialogClosed = function(event:DialogEvent) {
|
|
state.setUICheckboxSelected('menubarItemToggleToolboxEvents', false);
|
|
}
|
|
|
|
var toolboxEventsEventKind:DropDown = toolbox.findComponent('toolboxEventsEventKind', DropDown);
|
|
var toolboxEventsDataGrid:Grid = toolbox.findComponent('toolboxEventsDataGrid', Grid);
|
|
|
|
toolboxEventsEventKind.dataSource = new ArrayDataSource();
|
|
|
|
var songEvents:Array<SongEvent> = SongEventParser.listEvents();
|
|
|
|
for (event in songEvents)
|
|
{
|
|
toolboxEventsEventKind.dataSource.add({text: event.getTitle(), value: event.id});
|
|
}
|
|
|
|
toolboxEventsEventKind.onChange = function(event:UIEvent) {
|
|
var eventType:String = event.data.value;
|
|
|
|
trace('ChartEditorToolboxHandler.buildToolboxEventDataLayout() - Event type changed: $eventType');
|
|
|
|
var schema:SongEventSchema = SongEventParser.getEventSchema(eventType);
|
|
|
|
if (schema == null)
|
|
{
|
|
trace('ChartEditorToolboxHandler.buildToolboxEventDataLayout() - Unknown event kind: $eventType');
|
|
return;
|
|
}
|
|
|
|
buildEventDataFormFromSchema(state, toolboxEventsDataGrid, schema);
|
|
}
|
|
|
|
return toolbox;
|
|
}
|
|
|
|
static function onShowToolboxEventData(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
|
|
|
static function onHideToolboxEventData(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
|
|
|
static function buildEventDataFormFromSchema(state:ChartEditorState, target:Box, schema:SongEventSchema):Void
|
|
{
|
|
trace(schema);
|
|
// Clear the frame.
|
|
target.removeAllComponents();
|
|
|
|
state.selectedEventData = {};
|
|
|
|
for (field in schema)
|
|
{
|
|
// Add a label.
|
|
var label:Label = new Label();
|
|
label.text = field.title;
|
|
target.addComponent(label);
|
|
|
|
var input:Component;
|
|
switch (field.type)
|
|
{
|
|
case INTEGER:
|
|
var numberStepper:NumberStepper = new NumberStepper();
|
|
numberStepper.id = field.name;
|
|
numberStepper.step = field.step == null ? 1.0 : field.step;
|
|
numberStepper.min = field.min;
|
|
numberStepper.max = field.max;
|
|
numberStepper.value = field.defaultValue;
|
|
input = numberStepper;
|
|
case FLOAT:
|
|
var numberStepper:NumberStepper = new NumberStepper();
|
|
numberStepper.id = field.name;
|
|
numberStepper.step = field.step == null ? 0.1 : field.step;
|
|
numberStepper.min = field.min;
|
|
numberStepper.max = field.max;
|
|
numberStepper.value = field.defaultValue;
|
|
input = numberStepper;
|
|
case BOOL:
|
|
var checkBox:CheckBox = new CheckBox();
|
|
checkBox.id = field.name;
|
|
checkBox.selected = field.defaultValue;
|
|
input = checkBox;
|
|
case ENUM:
|
|
var dropDown:DropDown = new DropDown();
|
|
dropDown.id = field.name;
|
|
dropDown.dataSource = new ArrayDataSource();
|
|
|
|
// Add entries to the dropdown.
|
|
for (optionName in field.keys.keys())
|
|
{
|
|
var optionValue:String = field.keys.get(optionName);
|
|
trace('$optionName : $optionValue');
|
|
dropDown.dataSource.add({value: optionValue, text: optionName});
|
|
}
|
|
|
|
dropDown.value = field.defaultValue;
|
|
|
|
input = dropDown;
|
|
case STRING:
|
|
input = new TextField();
|
|
input.id = field.name;
|
|
input.text = field.defaultValue;
|
|
default:
|
|
// Unknown type. Display a label so we know what it is.
|
|
input = new Label();
|
|
input.id = field.name;
|
|
input.text = field.type;
|
|
}
|
|
|
|
target.addComponent(input);
|
|
|
|
input.onChange = function(event:UIEvent) {
|
|
trace('ChartEditorToolboxHandler.buildEventDataFormFromSchema() - ${event.target.id} = ${event.target.value}');
|
|
|
|
if (event.target.value == null) state.selectedEventData.remove(event.target.id);
|
|
else
|
|
state.selectedEventData.set(event.target.id, event.target.value);
|
|
}
|
|
}
|
|
}
|
|
|
|
static function buildToolboxDifficultyLayout(state:ChartEditorState):CollapsibleDialog
|
|
{
|
|
var toolbox:CollapsibleDialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_DIFFICULTY_LAYOUT);
|
|
|
|
if (toolbox == null) return null;
|
|
|
|
// Starting position.
|
|
toolbox.x = 125;
|
|
toolbox.y = 200;
|
|
|
|
toolbox.onDialogClosed = function(event:UIEvent) {
|
|
state.setUICheckboxSelected('menubarItemToggleToolboxDifficulty', false);
|
|
}
|
|
|
|
var difficultyToolboxSaveMetadata:Button = toolbox.findComponent('difficultyToolboxSaveMetadata', Button);
|
|
var difficultyToolboxSaveChart:Button = toolbox.findComponent('difficultyToolboxSaveChart', Button);
|
|
var difficultyToolboxSaveAll:Button = toolbox.findComponent('difficultyToolboxSaveAll', Button);
|
|
var difficultyToolboxLoadMetadata:Button = toolbox.findComponent('difficultyToolboxLoadMetadata', Button);
|
|
var difficultyToolboxLoadChart:Button = toolbox.findComponent('difficultyToolboxLoadChart', Button);
|
|
|
|
difficultyToolboxSaveMetadata.onClick = function(event:UIEvent) {
|
|
SongSerializer.exportSongMetadata(state.currentSongMetadata, state.currentSongId);
|
|
};
|
|
|
|
difficultyToolboxSaveChart.onClick = function(event:UIEvent) {
|
|
SongSerializer.exportSongChartData(state.currentSongChartData, state.currentSongId);
|
|
};
|
|
|
|
difficultyToolboxSaveAll.onClick = function(event:UIEvent) {
|
|
state.exportAllSongData();
|
|
};
|
|
|
|
difficultyToolboxLoadMetadata.onClick = function(event:UIEvent) {
|
|
// Replace metadata for current variation.
|
|
SongSerializer.importSongMetadataAsync(function(songMetadata) {
|
|
state.currentSongMetadata = songMetadata;
|
|
});
|
|
};
|
|
|
|
difficultyToolboxLoadChart.onClick = function(event:UIEvent) {
|
|
// Replace chart data for current variation.
|
|
SongSerializer.importSongChartDataAsync(function(songChartData) {
|
|
state.currentSongChartData = songChartData;
|
|
state.noteDisplayDirty = true;
|
|
});
|
|
};
|
|
|
|
state.difficultySelectDirty = true;
|
|
|
|
return toolbox;
|
|
}
|
|
|
|
static function onShowToolboxDifficulty(state:ChartEditorState, toolbox:CollapsibleDialog):Void
|
|
{
|
|
// Update the selected difficulty when reopening the toolbox.
|
|
var treeView:TreeView = toolbox.findComponent('difficultyToolboxTree');
|
|
if (treeView == null) return;
|
|
|
|
treeView.selectedNode = state.getCurrentTreeDifficultyNode(treeView);
|
|
trace('selected node: ${treeView.selectedNode}');
|
|
}
|
|
|
|
static function onHideToolboxDifficulty(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
|
|
|
static function buildToolboxMetadataLayout(state:ChartEditorState):CollapsibleDialog
|
|
{
|
|
var toolbox:CollapsibleDialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_METADATA_LAYOUT);
|
|
|
|
if (toolbox == null) return null;
|
|
|
|
// Starting position.
|
|
toolbox.x = 150;
|
|
toolbox.y = 250;
|
|
|
|
toolbox.onDialogClosed = function(event:UIEvent) {
|
|
state.setUICheckboxSelected('menubarItemToggleToolboxMetadata', false);
|
|
}
|
|
|
|
var inputSongName:TextField = toolbox.findComponent('inputSongName', TextField);
|
|
inputSongName.onChange = function(event:UIEvent) {
|
|
var valid:Bool = event.target.text != null && event.target.text != '';
|
|
|
|
if (valid)
|
|
{
|
|
inputSongName.removeClass('invalid-value');
|
|
state.currentSongMetadata.songName = event.target.text;
|
|
}
|
|
else
|
|
{
|
|
state.currentSongMetadata.songName = null;
|
|
}
|
|
};
|
|
inputSongName.value = state.currentSongMetadata.songName;
|
|
|
|
var inputSongArtist:TextField = toolbox.findComponent('inputSongArtist', TextField);
|
|
inputSongArtist.onChange = function(event:UIEvent) {
|
|
var valid:Bool = event.target.text != null && event.target.text != '';
|
|
|
|
if (valid)
|
|
{
|
|
inputSongArtist.removeClass('invalid-value');
|
|
state.currentSongMetadata.artist = event.target.text;
|
|
}
|
|
else
|
|
{
|
|
state.currentSongMetadata.artist = null;
|
|
}
|
|
};
|
|
inputSongArtist.value = state.currentSongMetadata.artist;
|
|
|
|
var inputStage:DropDown = toolbox.findComponent('inputStage', DropDown);
|
|
inputStage.onChange = function(event:UIEvent) {
|
|
var valid:Bool = event.data != null && event.data.id != null;
|
|
|
|
if (valid)
|
|
{
|
|
state.currentSongMetadata.playData.stage = event.data.id;
|
|
}
|
|
};
|
|
inputStage.value = state.currentSongMetadata.playData.stage;
|
|
|
|
var inputNoteSkin:DropDown = toolbox.findComponent('inputNoteSkin', DropDown);
|
|
inputNoteSkin.onChange = function(event:UIEvent) {
|
|
if ((event?.data?.id ?? null) == null) return;
|
|
state.currentSongMetadata.playData.noteSkin = event.data.id;
|
|
};
|
|
inputNoteSkin.value = state.currentSongMetadata.playData.noteSkin;
|
|
|
|
var inputBPM:NumberStepper = toolbox.findComponent('inputBPM', NumberStepper);
|
|
inputBPM.onChange = function(event:UIEvent) {
|
|
if (event.value == null || event.value <= 0) return;
|
|
|
|
var timeChanges:Array<SongTimeChange> = state.currentSongMetadata.timeChanges;
|
|
if (timeChanges == null || timeChanges.length == 0)
|
|
{
|
|
timeChanges = [new SongTimeChange(-1, 0, event.value, 4, 4, [4, 4, 4, 4])];
|
|
}
|
|
else
|
|
{
|
|
timeChanges[0].bpm = event.value;
|
|
}
|
|
|
|
Conductor.forceBPM(event.value);
|
|
|
|
state.currentSongMetadata.timeChanges = timeChanges;
|
|
};
|
|
inputBPM.value = state.currentSongMetadata.timeChanges[0].bpm;
|
|
|
|
var labelScrollSpeed:Label = toolbox.findComponent('labelScrollSpeed', Label);
|
|
|
|
var inputScrollSpeed:Slider = toolbox.findComponent('inputScrollSpeed', Slider);
|
|
inputScrollSpeed.onChange = function(event:UIEvent) {
|
|
var valid:Bool = event.target.value != null && event.target.value > 0;
|
|
|
|
if (valid)
|
|
{
|
|
inputScrollSpeed.removeClass('invalid-value');
|
|
state.currentSongChartScrollSpeed = event.target.value;
|
|
}
|
|
else
|
|
{
|
|
state.currentSongChartScrollSpeed = 1.0;
|
|
}
|
|
labelScrollSpeed.text = 'Scroll Speed: ${state.currentSongChartScrollSpeed}x';
|
|
};
|
|
inputScrollSpeed.value = state.currentSongChartScrollSpeed;
|
|
labelScrollSpeed.text = 'Scroll Speed: ${state.currentSongChartScrollSpeed}x';
|
|
|
|
var frameVariation:Frame = toolbox.findComponent('frameVariation', Frame);
|
|
frameVariation.text = 'Variation: ${state.selectedVariation.toTitleCase()}';
|
|
|
|
var frameDifficulty:Frame = toolbox.findComponent('frameDifficulty', Frame);
|
|
frameDifficulty.text = 'Difficulty: ${state.selectedDifficulty.toTitleCase()}';
|
|
|
|
return toolbox;
|
|
}
|
|
|
|
static function onShowToolboxMetadata(state:ChartEditorState, toolbox:CollapsibleDialog):Void
|
|
{
|
|
state.refreshSongMetadataToolbox();
|
|
}
|
|
|
|
static function onHideToolboxMetadata(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
|
|
|
static function buildToolboxCharactersLayout(state:ChartEditorState):CollapsibleDialog
|
|
{
|
|
var toolbox:CollapsibleDialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_CHARACTERS_LAYOUT);
|
|
|
|
if (toolbox == null) return null;
|
|
|
|
// Starting position.
|
|
toolbox.x = 175;
|
|
toolbox.y = 300;
|
|
|
|
toolbox.onDialogClosed = function(event:DialogEvent) {
|
|
state.setUICheckboxSelected('menubarItemToggleToolboxCharacters', false);
|
|
}
|
|
|
|
return toolbox;
|
|
}
|
|
|
|
static function onShowToolboxCharacters(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
|
|
|
static function onHideToolboxCharacters(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
|
|
|
static function buildToolboxPlayerPreviewLayout(state:ChartEditorState):CollapsibleDialog
|
|
{
|
|
var toolbox:CollapsibleDialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT);
|
|
|
|
if (toolbox == null) return null;
|
|
|
|
// Starting position.
|
|
toolbox.x = 200;
|
|
toolbox.y = 350;
|
|
|
|
toolbox.onDialogClosed = function(event:DialogEvent) {
|
|
state.setUICheckboxSelected('menubarItemToggleToolboxPlayerPreview', false);
|
|
}
|
|
|
|
var charPlayer:CharacterPlayer = toolbox.findComponent('charPlayer');
|
|
// TODO: We need to implement character swapping in ChartEditorState.
|
|
charPlayer.loadCharacter('bf');
|
|
charPlayer.characterType = CharacterType.BF;
|
|
charPlayer.flip = true;
|
|
charPlayer.targetScale = 0.5;
|
|
|
|
return toolbox;
|
|
}
|
|
|
|
static function onShowToolboxPlayerPreview(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
|
|
|
static function onHideToolboxPlayerPreview(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
|
|
|
static function buildToolboxOpponentPreviewLayout(state:ChartEditorState):CollapsibleDialog
|
|
{
|
|
var toolbox:CollapsibleDialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT);
|
|
|
|
if (toolbox == null) return null;
|
|
|
|
// Starting position.
|
|
toolbox.x = 200;
|
|
toolbox.y = 350;
|
|
|
|
toolbox.onDialogClosed = (event:DialogEvent) -> {
|
|
state.setUICheckboxSelected('menubarItemToggleToolboxOpponentPreview', false);
|
|
}
|
|
|
|
var charPlayer:CharacterPlayer = toolbox.findComponent('charPlayer');
|
|
// TODO: We need to implement character swapping in ChartEditorState.
|
|
charPlayer.loadCharacter('dad');
|
|
charPlayer.characterType = CharacterType.DAD;
|
|
charPlayer.flip = false;
|
|
charPlayer.targetScale = 0.5;
|
|
|
|
return toolbox;
|
|
}
|
|
|
|
static function onShowToolboxOpponentPreview(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
|
|
|
static function onHideToolboxOpponentPreview(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
|
}
|