From 6da6c9426d2692e7547b3ff73906a682bcf105f6 Mon Sep 17 00:00:00 2001 From: DeltaNedas Date: Tue, 10 Nov 2020 08:02:39 +0000 Subject: [PATCH] add file picker interface for mods --- .../mindustry/android/AndroidLauncher.java | 10 ++--- core/assets/scripts/base.js | 15 ++++--- core/assets/scripts/global.js | 5 +++ core/src/mindustry/core/Platform.java | 9 ++++- core/src/mindustry/mod/Scripts.java | 40 +++++++++++++++++++ ios/src/mindustry/ios/IOSLauncher.java | 2 +- 6 files changed, 68 insertions(+), 13 deletions(-) diff --git a/android/src/mindustry/android/AndroidLauncher.java b/android/src/mindustry/android/AndroidLauncher.java index 42dc7ef931..6e3a05c11d 100644 --- a/android/src/mindustry/android/AndroidLauncher.java +++ b/android/src/mindustry/android/AndroidLauncher.java @@ -77,11 +77,11 @@ public class AndroidLauncher extends AndroidApplication{ } @Override - public void showFileChooser(boolean open, String extension, Cons cons){ - showFileChooser(open, cons, extension); + public void showFileChooser(boolean open, String title, String extension, Cons cons){ + showFileChooser(open, title, cons, extension); } - void showFileChooser(boolean open, Cons cons, String... extensions){ + void showFileChooser(boolean open, String title, Cons cons, String... extensions){ String extension = extensions[0]; if(VERSION.SDK_INT >= VERSION_CODES.Q){ @@ -118,7 +118,7 @@ public class AndroidLauncher extends AndroidApplication{ }); }else if(VERSION.SDK_INT >= VERSION_CODES.M && !(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)){ - chooser = new FileChooser(open ? "@open" : "@save", file -> Structs.contains(extensions, file.extension().toLowerCase()), open, file -> { + chooser = new FileChooser(title, file -> Structs.contains(extensions, file.extension().toLowerCase()), open, file -> { if(!open){ cons.get(file.parent().child(file.nameWithoutExtension() + "." + extension)); }else{ @@ -136,7 +136,7 @@ public class AndroidLauncher extends AndroidApplication{ requestPermissions(perms.toArray(new String[0]), PERMISSION_REQUEST_CODE); }else{ if(open){ - new FileChooser("@open", file -> Structs.contains(extensions, file.extension().toLowerCase()), true, cons).show(); + new FileChooser(title, file -> Structs.contains(extensions, file.extension().toLowerCase()), true, cons).show(); }else{ super.showFileChooser(open, extension, cons); } diff --git a/core/assets/scripts/base.js b/core/assets/scripts/base.js index ace7d878ee..1cf5ecd2e2 100755 --- a/core/assets/scripts/base.js +++ b/core/assets/scripts/base.js @@ -1,13 +1,18 @@ "use strict"; const log = function(context, obj){ - Vars.mods.getScripts().log(context, String(obj)) + Vars.mods.scripts.log(context, String(obj)) } -const readString = path => Vars.mods.getScripts().readString(path) -const readBytes = path => Vars.mods.getScripts().readBytes(path) -const loadMusic = path => Vars.mods.getScripts().loadMusic(path) -const loadSound = path => Vars.mods.getScripts().loadSound(path) +const readString = path => Vars.mods.scripts.readString(path) +const readBytes = path => Vars.mods.scripts.readBytes(path) +const loadMusic = path => Vars.mods.scripts.loadMusic(path) +const loadSound = path => Vars.mods.scripts.loadSound(path) + +const readFile = (purpose, ext, cons) => Vars.mods.scripts.readFile(purpose, ext, cons); +const readBinFile = (purpose, ext, cons) => Vars.mods.scripts.readBinFile(purpose, ext, cons); +const writeFile = (purpose, ext, str) => Vars.mods.scripts.writeFile(purpose, ext, str); +const writeBinFile = (purpose, ext, bytes) => Vars.mods.scripts.writeBinFile(purpose, ext, bytes); let scriptName = "base.js" let modName = "none" diff --git a/core/assets/scripts/global.js b/core/assets/scripts/global.js index e937b0cd75..16adb1d149 100755 --- a/core/assets/scripts/global.js +++ b/core/assets/scripts/global.js @@ -11,6 +11,11 @@ const readBytes = path => Vars.mods.getScripts().readBytes(path) const loadMusic = path => Vars.mods.getScripts().loadMusic(path) const loadSound = path => Vars.mods.getScripts().loadSound(path) +const readFile = (purpose, ext, cons) => Vars.mods.scripts.readFile(purpose, ext, cons); +const readBinFile = (purpose, ext, cons) => Vars.mods.scripts.readBinFile(purpose, ext, cons); +const writeFile = (purpose, ext, str) => Vars.mods.scripts.writeFile(purpose, ext, str); +const writeBinFile = (purpose, ext, bytes) => Vars.mods.scripts.writeBinFile(purpose, ext, bytes); + let scriptName = "base.js" let modName = "none" diff --git a/core/src/mindustry/core/Platform.java b/core/src/mindustry/core/Platform.java index 7eae8136c0..1e77fbbe61 100644 --- a/core/src/mindustry/core/Platform.java +++ b/core/src/mindustry/core/Platform.java @@ -117,9 +117,10 @@ public interface Platform{ * @param cons Selection listener * @param open Whether to open or save files * @param extension File extension to filter + * @param title The title of the native dialog */ - default void showFileChooser(boolean open, String extension, Cons cons){ - new FileChooser(open ? "@open" : "@save", file -> file.extEquals(extension), open, file -> { + default void showFileChooser(boolean open, String title, String extension, Cons cons){ + new FileChooser(title, file -> file.extEquals(extension), open, file -> { if(!open){ cons.get(file.parent().child(file.nameWithoutExtension() + "." + extension)); }else{ @@ -128,6 +129,10 @@ public interface Platform{ }).show(); } + default void showFileChooser(boolean open, String extension, Cons cons){ + showFileChooser(open, open ? "@open": "@save", extension, cons); + } + /** * Show a file chooser for multiple file types. * @param cons Selection listener diff --git a/core/src/mindustry/mod/Scripts.java b/core/src/mindustry/mod/Scripts.java index bd7a73a34a..dce6350d89 100644 --- a/core/src/mindustry/mod/Scripts.java +++ b/core/src/mindustry/mod/Scripts.java @@ -4,7 +4,9 @@ import arc.*; import arc.assets.*; import arc.audio.*; import arc.files.*; +import arc.func.*; import arc.mock.*; +import arc.scene.ui.*; import arc.struct.*; import arc.util.*; import arc.util.Log.*; @@ -116,6 +118,44 @@ public class Scripts implements Disposable{ return sound; } + /** Ask the user to select a file to read for a certain purpose like "Please upload a sprite" */ + public void readFile(String purpose, String ext, Cons cons){ + selectFile(true, purpose, ext, fi -> cons.get(fi.readString())); + } + + /** readFile but for a byte[] */ + public void readBinFile(String purpose, String ext, Cons cons){ + selectFile(true, purpose, ext, fi -> cons.get(fi.readBytes())); + } + + /** Ask the user to write a file. */ + public void writeFile(String purpose, String ext, String contents){ + if(contents == null) contents = ""; + final String fContents = contents; + selectFile(false, purpose, ext, fi -> fi.writeString(fContents)); + } + + /** writeFile but for a byte[] */ + public void writeBinFile(String purpose, String ext, byte[] contents){ + if(contents == null) contents = new byte[0]; + final byte[] fContents = contents; + selectFile(false, purpose, ext, fi -> fi.writeBytes(fContents)); + } + + private void selectFile(boolean open, String purpose, String ext, Cons cons){ + purpose = purpose.startsWith("@") ? Core.bundle.get(purpose.substring(1)) : purpose; + //add purpose and extension at the top + String title = Core.bundle.get(open ? "open" : "save") + " - " + purpose + " (." + ext + ")"; + Vars.platform.showFileChooser(open, title, ext, fi -> { + try{ + cons.get(fi); + }catch(Exception e){ + Log.err("Failed to select file '@' for a mod", fi); + Log.err(e); + } + }); + } + //endregion public void run(LoadedMod mod, Fi file){ diff --git a/ios/src/mindustry/ios/IOSLauncher.java b/ios/src/mindustry/ios/IOSLauncher.java index e876eaa59d..818ea50a0f 100644 --- a/ios/src/mindustry/ios/IOSLauncher.java +++ b/ios/src/mindustry/ios/IOSLauncher.java @@ -42,7 +42,7 @@ public class IOSLauncher extends IOSApplication.Delegate{ return new IOSApplication(new ClientLauncher(){ @Override - public void showFileChooser(boolean open, String extension, Cons cons){ + public void showFileChooser(boolean open, String titleIgn, String extension, Cons cons){ if(!open){ //when exporting, just share it. //ask for export name Core.input.getTextInput(new TextInput(){{