diff --git a/assets/images/editors/charter/audio-buttons.png b/assets/images/editors/charter/audio-buttons.png new file mode 100644 index 00000000..be968ca1 Binary files /dev/null and b/assets/images/editors/charter/audio-buttons.png differ diff --git a/assets/images/editors/charter/upload-button.png b/assets/images/editors/charter/upload-button.png new file mode 100644 index 00000000..6993f74f Binary files /dev/null and b/assets/images/editors/charter/upload-button.png differ diff --git a/source/funkin/editors/charter/SongCreationScreen.hx b/source/funkin/editors/charter/SongCreationScreen.hx index d6967892..4026e242 100644 --- a/source/funkin/editors/charter/SongCreationScreen.hx +++ b/source/funkin/editors/charter/SongCreationScreen.hx @@ -18,6 +18,8 @@ class SongCreationScreen extends UISubstateWindow { public var beatsPerMesureStepper:UINumericStepper; public var stepsPerBeatStepper :UINumericStepper; public var needsVoicesCheckbox:UICheckbox; + public var instExplorer:UIFileExplorer; + public var voicesExplorer:UIFileExplorer; public var displayNameTextBox:UITextBox; public var iconTextBox:UITextBox; @@ -79,6 +81,22 @@ class SongCreationScreen extends UISubstateWindow { addLabelOn(needsVoicesCheckbox, "Needs Voices"); needsVoicesCheckbox.y += 6; needsVoicesCheckbox.x += 4; + instExplorer = new UIFileExplorer(songNameTextBox.x, songNameTextBox.y + 32 + 36, #if html5 "mp3" #else "ogg" #end, function (res) { + var audioPlayer:UIAudioPlayer = new UIAudioPlayer(instExplorer.x + 16, instExplorer.y + 8, res); + instExplorer.members.push(audioPlayer); + instExplorer.uiElement = audioPlayer; + }); + songDataGroup.add(instExplorer); + addLabelOn(instExplorer, "Inst Audio File"); + + voicesExplorer = new UIFileExplorer(instExplorer.x + 320 + 26, instExplorer.y, #if html5 "mp3" #else "ogg" #end, function (res) { + var audioPlayer:UIAudioPlayer = new UIAudioPlayer(voicesExplorer.x + 16, voicesExplorer.y + 8, res); + voicesExplorer.members.push(audioPlayer); + voicesExplorer.uiElement = audioPlayer; + }); + songDataGroup.add(voicesExplorer); + addLabelOn(voicesExplorer, "Vocal Audio File"); + var menuTitle:UIText; menuDataGroup.add(menuTitle = new UIText(windowSpr.x + 20, windowSpr.y + 30 + 16, 0, "Menus Data (Freeplay/Story)", 28)); @@ -139,7 +157,7 @@ class SongCreationScreen extends UISubstateWindow { closeButton.color = 0xFFFF0000; pages.push(cast add(songDataGroup)); - pageSizes.push(FlxPoint.get(748 - 32 + 40, 520)); + pageSizes.push(FlxPoint.get(748 - 32 + 40, 340)); pages.push(cast add(menuDataGroup)); pageSizes.push(FlxPoint.get(748 - 32 + 40, 400)); diff --git a/source/funkin/editors/ui/UIAudioPlayer.hx b/source/funkin/editors/ui/UIAudioPlayer.hx new file mode 100644 index 00000000..797cfa52 --- /dev/null +++ b/source/funkin/editors/ui/UIAudioPlayer.hx @@ -0,0 +1,46 @@ +package funkin.editors.ui; + +import flixel.sound.FlxSound; +import haxe.io.Bytes; +import lime.media.AudioBuffer; +import openfl.media.Sound; + +class UIAudioPlayer extends UIButton { + public var sound:FlxSound; + public var bytes:Bytes; + + public var playingSprite:FlxSprite; + public var timeText:UIText; + + public function new(x:Float, y:Float, bytes:Bytes) { + sound = FlxG.sound.load(Sound.fromAudioBuffer(AudioBuffer.fromBytes(bytes))); + + super(x, y, "", function () { + if (sound.playing) sound.pause(); + else sound.play(); + }, 58 - 18, 58 - 18); + + playingSprite = new FlxSprite(x + ((58 - 18)/2) - 8, y + ((58 - 18)/2) - 8).loadGraphic(Paths.image('editors/charter/audio-buttons'), true, 16, 16); + playingSprite.animation.add("paused", [0]); + playingSprite.animation.add("playing", [1]); + playingSprite.antialiasing = false; + playingSprite.updateHitbox(); + members.push(playingSprite); + + } + + public override function update(elapsed:Float) { + super.update(elapsed); + + if (sound != null) + playingSprite.animation.play(sound.playing ? "playing" : "paused"); + } + + public override function destroy() { + super.destroy(); + + sound.stop(); + @:privateAccess sound.reset(); + bytes = null; + } +} \ No newline at end of file diff --git a/source/funkin/editors/ui/UIFileExplorer.hx b/source/funkin/editors/ui/UIFileExplorer.hx new file mode 100644 index 00000000..d4880400 --- /dev/null +++ b/source/funkin/editors/ui/UIFileExplorer.hx @@ -0,0 +1,59 @@ +package funkin.editors.ui; + +import haxe.io.Bytes; +import lime.ui.FileDialog; + +class UIFileExplorer extends UISliceSprite { + public var uploadButton:UIButton; + public var uploadIcon:FlxSprite; + + public var deleteButton:UIButton; + public var deleteIcon:FlxSprite; + + public var file:Bytes = null; + public var onFile:Bytes->Void; + + public var uiElement:UISprite; + + public function new(x:Float, y:Float, fileType:String = "txt", ?onFile:Bytes->Void) { + super(x, y, 320, 58, 'editors/ui/inputbox'); + + if (onFile != null) this.onFile = onFile; + + uploadButton = new UIButton(x + 8, y+ 8, "", function () { + var fileDialog = new FileDialog(); + fileDialog.onOpen.add(function(res) { + file = cast res; + deleteButton.visible = deleteButton.selectable = deleteIcon.visible = !(uploadButton.visible = uploadButton.selectable = false); + + if (this.onFile != null) this.onFile(file); + }); + fileDialog.open(fileType); + }, 320 - 16, 58 - 18); + members.push(uploadButton); + + uploadIcon = new FlxSprite(uploadButton.x + (uploadButton.bWidth / 2) - 8, uploadButton.y + ((58-18)/2) - 8).loadGraphic(Paths.image('editors/charter/upload-button')); + uploadIcon.antialiasing = false; + uploadButton.members.push(uploadIcon); + + deleteButton = new UIButton(x + 320 - (58 - 18) - 16, y + 8, "", function () { + if (uiElement != null) { + members.remove(uiElement); + uiElement.destroy(); + } + + file = null; + MemoryUtil.clearMajor(); + + deleteButton.visible = deleteButton.selectable = deleteIcon.visible = !(uploadButton.visible = uploadButton.selectable = true); + }, 58 - 18, 58 - 18); + deleteButton.color = 0xFFFF0000; + members.push(deleteButton); + + deleteIcon = new FlxSprite(deleteButton.x + ((58 - 18)/2) - 8, deleteButton.y + ((58 - 18)/2) - 8).loadGraphic(Paths.image('editors/character/delete-button')); + deleteIcon.antialiasing = false; + members.push(deleteIcon); + + deleteButton.visible = deleteButton.selectable = deleteIcon.visible = false; + } +} \ No newline at end of file