From a7aa600ed6021e7931851fcd72c6e8eaefe0803a Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 2 Jun 2024 16:11:29 -0400 Subject: [PATCH] Native multi file chooser --- core/src/mindustry/core/Platform.java | 102 +++++++++++++++----------- 1 file changed, 59 insertions(+), 43 deletions(-) diff --git a/core/src/mindustry/core/Platform.java b/core/src/mindustry/core/Platform.java index 77d62c6bf0..84e67a9f23 100644 --- a/core/src/mindustry/core/Platform.java +++ b/core/src/mindustry/core/Platform.java @@ -143,49 +143,7 @@ public interface Platform{ */ default void showFileChooser(boolean open, String title, String extension, Cons cons){ if(OS.isWindows || OS.isMac){ - String formatted = (title.startsWith("@") ? Core.bundle.get(title.substring(1)) : title).replaceAll("\"", "'"); - - //native file dialog - Threads.daemon(() -> { - try{ - FileDialogs.loadNatives(); - - String result; - //on MacOS, .msav is not properly recognized until I put garbage into the array? - String[] extensions = OS.isMac && open ? new String[]{"", "*." + extension} : new String[]{"*." + extension}; - - if(open){ - result = FileDialogs.openFileDialog(formatted, FileChooser.getLastDirectory().absolutePath(), extensions, "." + extension + " files", false); - }else{ - result = FileDialogs.saveFileDialog(formatted, FileChooser.getLastDirectory().child("file." + extension).absolutePath(), extensions, "." + extension + " files"); - } - - if(result == null) return; - - if(result.length() > 1 && result.contains("\n")){ - result = result.split("\n")[0]; - } - - //cancelled selection, ignore result - if(result.isEmpty() || result.equals("\n")) return; - if(result.endsWith("\n")) result = result.substring(0, result.length() - 1); - if(result.contains("\n")) throw new IOException("invalid input: \"" + result + "\""); - - Fi file = Core.files.absolute(result); - Core.app.post(() -> { - FileChooser.setLastDirectory(file.isDirectory() ? file : file.parent()); - - if(!open){ - cons.get(file.parent().child(file.nameWithoutExtension() + "." + extension)); - }else{ - cons.get(file); - } - }); - }catch(Throwable error){ - Log.err("Failure to execute native file chooser", error); - Core.app.post(() -> defaultFileDialog(open, title, extension, cons)); - } - }); + showNativeFileChooser(open, title, cons, extension); }else if(OS.isLinux && !OS.isAndroid){ showZenity(open, title, new String[]{extension}, cons, () -> defaultFileDialog(open, title, extension, cons)); }else{ @@ -268,6 +226,8 @@ public interface Platform{ default void showMultiFileChooser(Cons cons, String... extensions){ if(mobile){ showFileChooser(true, extensions[0], cons); + }else if(OS.isWindows || OS.isMac){ + showNativeFileChooser(true, "@open", cons, extensions); }else if(OS.isLinux && !OS.isAndroid){ showZenity(true, "@open", extensions, cons, () -> defaultMultiFileChooser(cons, extensions)); }else{ @@ -279,6 +239,62 @@ public interface Platform{ new FileChooser("@open", file -> Structs.contains(extensions, file.extension().toLowerCase()), true, cons).show(); } + default void showNativeFileChooser(boolean open, String title, Cons cons, String... shownExtensions){ + String formatted = (title.startsWith("@") ? Core.bundle.get(title.substring(1)) : title).replaceAll("\"", "'"); + + //this should never happen unless someone is being dumb with the parameters + String[] ext = shownExtensions == null || shownExtensions.length == 0 ? new String[]{""} : shownExtensions; + + //native file dialog + Threads.daemon(() -> { + try{ + FileDialogs.loadNatives(); + + String result; + String[] patterns = new String[ext.length]; + for(int i = 0; i < ext.length; i++){ + patterns[i] = "*." + ext[i]; + } + + //on MacOS, .msav is not properly recognized until I put garbage into the array? + if(patterns.length == 1 && OS.isMac && open){ + patterns = new String[]{"", "*." + ext[0]}; + } + + if(open){ + result = FileDialogs.openFileDialog(formatted, FileChooser.getLastDirectory().absolutePath(), patterns, "." + ext[0] + " files", false); + }else{ + result = FileDialogs.saveFileDialog(formatted, FileChooser.getLastDirectory().child("file." + ext[0]).absolutePath(), patterns, "." + ext[0] + " files"); + } + + if(result == null) return; + + if(result.length() > 1 && result.contains("\n")){ + result = result.split("\n")[0]; + } + + //cancelled selection, ignore result + if(result.isEmpty() || result.equals("\n")) return; + if(result.endsWith("\n")) result = result.substring(0, result.length() - 1); + if(result.contains("\n")) throw new IOException("invalid input: \"" + result + "\""); + + Fi file = Core.files.absolute(result); + Core.app.post(() -> { + FileChooser.setLastDirectory(file.isDirectory() ? file : file.parent()); + + if(!open){ + cons.get(file.parent().child(file.nameWithoutExtension() + "." + ext[0])); + }else{ + cons.get(file); + } + }); + }catch(Throwable error){ + Log.err("Failure to execute native file chooser", error); + Core.app.post(() -> defaultFileDialog(open, title, ext[0], cons)); + } + }); + } + /** Hide the app. Android only. */ default void hide(){ }