diff --git a/source/funkin/editors/character/CharacterCreationScreen.hx b/source/funkin/editors/character/CharacterCreationScreen.hx index d844b965..5bb5062e 100644 --- a/source/funkin/editors/character/CharacterCreationScreen.hx +++ b/source/funkin/editors/character/CharacterCreationScreen.hx @@ -41,7 +41,7 @@ class CharacterCreationScreen extends UISubstateWindow { "Character File Name $* Required$", [new FlxTextFormatMarkerPair(new FlxTextFormat(0xFFAD1212), "$")]); - imageExplorer = new UIImageExplorer(characterNameTextBox.x, characterNameTextBox.y + 30 + 16 + 20, null, 320, 58, (_, _) -> {onLoadImage();}); + imageExplorer = new UIImageExplorer(characterNameTextBox.x, characterNameTextBox.y + 30 + 16 + 20, null, 320, 58, (_, _) -> {onLoadImage();}, "images/characters"); add(imageExplorer); addLabelOn(imageExplorer, "Character Image File").applyMarkup( "Character Image File $* Required$", @@ -88,7 +88,7 @@ class CharacterCreationScreen extends UISubstateWindow { var xml:Xml = Xml.createElement("character"); xml.attributeOrder = Character.characterProperties.copy(); - xml.set("sprite", imageSaveData.imageName); + xml.set("sprite", '${imageSaveData.directory.length > 0 ? '${imageSaveData.directory}/' : ""}' + imageSaveData.imageName); // Look for animations >:D var animationList:Array = imageExplorer.animationList.copy(); diff --git a/source/funkin/editors/character/CharacterSpriteScreen.hx b/source/funkin/editors/character/CharacterSpriteScreen.hx index cdf2f7ee..a3497127 100644 --- a/source/funkin/editors/character/CharacterSpriteScreen.hx +++ b/source/funkin/editors/character/CharacterSpriteScreen.hx @@ -34,7 +34,7 @@ class CharacterSpriteScreen extends UISubstateWindow { super.create(); - imageExplorer = new UIImageExplorer(20, windowSpr.y + 30 + 16 + 20, imagePath, 320, 58, (_, _) -> {onLoadImage();}); + imageExplorer = new UIImageExplorer(20, windowSpr.y + 30 + 16 + 20, imagePath, 320, 58, (_, _) -> {onLoadImage();}, "images/characters"); add(imageExplorer); addLabelOn(imageExplorer, "Character Image File").applyMarkup( "Character Image File $* Required$", @@ -45,7 +45,7 @@ class CharacterSpriteScreen extends UISubstateWindow { saveButton = new UIButton(windowSpr.x + windowSpr.bWidth - 20, windowSpr.y + windowSpr.bHeight - 20, "Save & Close", function() { addToUndo(); // should be async?? -lunar imageExplorer.saveFiles('${Paths.getAssetsRoot()}/images/characters', () -> { - onSave(imageExplorer.imageName, imageExplorer.isAtlas); + onSave('${imageExplorer.saveData.directory.length > 0 ? '${imageExplorer.saveData.directory}/' : ""}' + imageExplorer.imageName, imageExplorer.isAtlas); close(); }); }, 125); diff --git a/source/funkin/editors/ui/UIImageExplorer.hx b/source/funkin/editors/ui/UIImageExplorer.hx index 8101e2ce..ecf98e19 100644 --- a/source/funkin/editors/ui/UIImageExplorer.hx +++ b/source/funkin/editors/ui/UIImageExplorer.hx @@ -18,6 +18,7 @@ using flixel.util.FlxSpriteUtil; typedef ImageSaveData = { var imageName:String; + var directory:String; var isAtlas:Bool; var imageFiles:Map>; } @@ -25,16 +26,36 @@ typedef ImageSaveData = { // TODO: make this limited if on web class UIImageExplorer extends UIFileExplorer { private var allowAtlases:Bool = true; + private var allowDirectories:Bool = true; - public function new(x:Float, y:Float, image:String, ?w:Int, ?h:Int, ?onFile:(String, Bytes)->Void) { + public var directoryButton:UIButton; + public var directoryIcon:UIText; + + public var directoryBG:UISliceSprite; + public var directoryTextBoxLabel:UIText; + public var directoryTextBox:UITextBox; + + public function new(x:Float, y:Float, image:String, ?w:Int, ?h:Int, ?onFile:(String, Bytes)->Void, ?directory:String = "images") { super(x, y, w, h, "png, jpg", function (filePath, file) { if (filePath != null && file != null) uploadImage(filePath, file); if (onFile != null) onFile(filePath, file); }); - + deleteButton.bWidth = 26; deleteButton.bHeight = 26; + directoryButton = new UIButton(x + bWidth - (bHeight - 16) - 8, y + 8, null, () -> {directoryBG.visible = !directoryBG.visible;}, 26, 26); + members.push(directoryButton); + + directoryIcon = new UIText(directoryButton.x, directoryButton.y, 0, "/", 14); + members.push(directoryIcon); + + directoryBG = new UISliceSprite(0, 0, 210+16, 8+12+4+22+8, 'editors/ui/inputbox'); + directoryBG.alpha = 0.9; directoryBG.members.push(directoryTextBoxLabel = new UIText(8, 6, 0, 'Directory ($directory/)', 12)); + + directoryTextBox = new UITextBox(8, 8+12+4, "", 210, 22, false, true); + directoryBG.members.push(directoryTextBox); + if (image != null) { var fullImagePath:String = '${Path.normalize(Sys.getCwd())}/${Paths.image(image)}'.replace('/', '\\'); var noExt = Path.withoutExtension(fullImagePath); @@ -44,6 +65,9 @@ class UIImageExplorer extends UIFileExplorer { if (FileSystem.exists(fullImagePath)) loadFile(fullImagePath); } + + allowDirectories = CoolUtil.isMapEmpty(imageFiles); __firstLoad = false; + directoryButton.visible = directoryButton.selectable = directoryIcon.visible = directoryBG.visible = false; } public var isAtlas:Bool = false; @@ -60,6 +84,7 @@ class UIImageExplorer extends UIFileExplorer { public var maxSize:FlxPoint = FlxPoint.get(700, 500); + @:noCompletion var __firstLoad:Bool = true; public function uploadImage(filePath:String, file:Bytes) { __resetData(); @@ -205,12 +230,12 @@ class UIImageExplorer extends UIFileExplorer { uiElement.antialiasing = true; members.push(uiElement); - if (!isAtlas && frames != null) { - for (frame in frames.frames) { - var rect = frame.frame; - uiElement.drawRect(rect.x, rect.y, rect.width, rect.height, 0x00161E87, {thickness: Std.int(1.75/imageScale), color: 0xFF11178C}); - } - } + //if (!isAtlas && frames != null) { + // for (frame in frames.frames) { + // var rect = frame.frame; + // uiElement.drawRect(rect.x, rect.y, rect.width, rect.height, 0x00161E87, {thickness: Std.int(1.75/imageScale), color: 0xFF11178C}); + // } + //} // GENERATE TEXT!!! imagePath = new Path(imagePath); imageName = isAtlas ? Path.withoutDirectory(directoryPath) : imagePath.file; @@ -241,11 +266,36 @@ class UIImageExplorer extends UIFileExplorer { deleteIcon.x = deleteButton.x + deleteButton.bWidth/2 - 8; deleteIcon.y = deleteButton.y + deleteButton.bHeight/2 - 8; + + directoryButton.x = deleteButton.x - deleteButton.bWidth - 12; + directoryButton.y = y + 12; + + directoryIcon.x = directoryButton.x + directoryButton.bWidth/2 - (directoryIcon.width/2); + directoryIcon.y = directoryButton.y + directoryButton.bHeight/2 - (directoryIcon.height/2); + + directoryBG.x = x + bWidth - directoryBG.bWidth - 16; + directoryBG.y = directoryButton.y + directoryButton.bHeight + 8; + + directoryTextBoxLabel.x = directoryBG.x + 8; + directoryTextBoxLabel.y = directoryBG.y + 6; + + directoryTextBox.x = directoryBG.x + 8; + directoryTextBox.y = directoryBG.y + 8+12+4; + + if (!__firstLoad) allowDirectories = true; + + directoryButton.visible = directoryButton.selectable = directoryIcon.visible = allowDirectories; + directoryBG.visible = false; + if (directoryButton.visible) fileText.fieldWidth -= directoryButton.bWidth + 12; + + members.push(directoryBG); __firstLoad = false; } + public var saveData:ImageSaveData = null; public inline function getSaveData():ImageSaveData { - return { + return saveData = { imageName: this.imageName, + directory: Path.removeTrailingSlashes(directoryTextBox.label.text), isAtlas: this.isAtlas, imageFiles: this.imageFiles.copy() }; @@ -262,6 +312,7 @@ class UIImageExplorer extends UIFileExplorer { return cast haxe.Unserializer.run(data); public static function saveFilesGlobal(imageData:ImageSaveData, directory:String, ?onFinishSaving:Void->Void, ?checkExisting:Bool = true) { + directory += '${directory.length > 0 ? '/${imageData.directory}' : ""}'; if (imageData.isAtlas) directory += '/${imageData.imageName}'; var alreadlyExistingFiles:Array = []; @@ -311,6 +362,9 @@ class UIImageExplorer extends UIFileExplorer { members.remove(fileText); fileText.destroy(); + members.remove(directoryBG); + directoryButton.visible = directoryButton.selectable = directoryIcon.visible = directoryBG.visible = false; + super.removeFile(); }