diff --git a/.gitignore b/.gitignore index ee86d3949c..296fbf66f7 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ /desktop/mindustry-maps/ /desktop/gifexport/ /core/lib/ +/annotations/build/ /kryonet/build/ /server/build/ /android/assets/mindustry-maps/ diff --git a/core/assets/sprites/icon.icns b/core/assets/sprites/icon.icns index 93771cc76c..c2ef55f248 100644 Binary files a/core/assets/sprites/icon.icns and b/core/assets/sprites/icon.icns differ diff --git a/core/assets/sprites/icon@2x.icns b/core/assets/sprites/icon@2x.icns new file mode 100644 index 0000000000..7d3530cefa Binary files /dev/null and b/core/assets/sprites/icon@2x.icns differ diff --git a/core/src/io/anuke/mindustry/core/Platform.java b/core/src/io/anuke/mindustry/core/Platform.java index 5f88611cd3..b508f66b4c 100644 --- a/core/src/io/anuke/mindustry/core/Platform.java +++ b/core/src/io/anuke/mindustry/core/Platform.java @@ -6,6 +6,7 @@ import io.anuke.mindustry.core.ThreadHandler.ThreadProvider; import io.anuke.ucore.core.Settings; import io.anuke.ucore.entities.Entity; import io.anuke.ucore.entities.EntityGroup; +import io.anuke.ucore.function.Consumer; import io.anuke.ucore.scene.ui.TextField; import java.util.Date; @@ -63,6 +64,8 @@ public abstract class Platform { } /**Only used for iOS or android: open the share menu for a map or save.*/ public void shareFile(FileHandle file){} + /**Show a file chooser. Desktop only.*/ + public void showFileChooser(String text, String content, Consumer cons, boolean open, String... filetypes){} /**Use the default thread provider from the kryonet module for this.*/ public ThreadProvider getThreadProvider(){ return new ThreadProvider() { diff --git a/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java b/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java index ed02ad4cbf..7a5ed16c6d 100644 --- a/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java +++ b/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java @@ -6,7 +6,6 @@ import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import io.anuke.mindustry.core.Platform; -import io.anuke.mindustry.ui.dialogs.FileChooser; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.ColorMapper; import io.anuke.mindustry.world.ColorMapper.BlockPair; @@ -43,7 +42,6 @@ public class MapEditorDialog extends Dialog{ private MapSaveDialog saveDialog; private MapResizeDialog resizeDialog; private ScrollPane pane; - private FileChooser openFile, saveFile; private boolean saved = false; private ButtonGroup blockgroup; @@ -56,25 +54,6 @@ public class MapEditorDialog extends Dialog{ dialog = new MapGenerateDialog(editor); view = new MapView(editor); - openFile = new FileChooser("$text.loadimage", FileChooser.pngFilter, true, this::tryLoadMap); - - saveFile = new FileChooser("$saveimage", false, file -> { - if(!file.extension().toLowerCase().equals(".png")){ - file = file.parent().child(file.nameWithoutExtension() + ".png"); - } - FileHandle result = file; - ui.loadfrag.show(); - Timers.run(3f, () -> { - try{ - Pixmaps.write(editor.pixmap(), result); - }catch (Exception e){ - ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false))); - if(!mobile) Log.err(e); - } - ui.loadfrag.hide(); - }); - }); - loadDialog = new MapLoadDialog(map -> { saveDialog.setFieldText(map.name); ui.loadfrag.show(); @@ -225,9 +204,9 @@ public class MapEditorDialog extends Dialog{ //iOS does not support loading raw files. if(!ios) { - new imagebutton("icon-load-image", isize, () -> - openFile.show() - ).text("$text.editor.loadimage"); + new imagebutton("icon-load-image", isize, () -> { + Platform.instance.showFileChooser(Bundles.get("text.loadimage"), "Image Files", MapEditorDialog.this::tryLoadMap, true, "png"); + }).text("$text.editor.loadimage"); row(); } @@ -235,7 +214,22 @@ public class MapEditorDialog extends Dialog{ new imagebutton("icon-save-image", isize, () -> { //iOS doesn't really support saving raw files. Sharing is used instead. if(!ios){ - saveFile.show(); + Platform.instance.showFileChooser(Bundles.get("text.saveimage"), "Image Files", file -> { + if(!file.extension().toLowerCase().equals(".png")){ + file = file.parent().child(file.nameWithoutExtension() + ".png"); + } + FileHandle result = file; + ui.loadfrag.show(); + Timers.run(3f, () -> { + try{ + Pixmaps.write(editor.pixmap(), result); + }catch (Exception e){ + ui.showError(Bundles.format("text.editor.errorimagesave", Strings.parseException(e, false))); + if(!mobile) Log.err(e); + } + ui.loadfrag.hide(); + }); + }, false, "png"); }else{ try{ FileHandle file = Gdx.files.local(("map-" + ((editor.getMap().name == null) ? "unknown" : editor.getMap().name) + ".png")); diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java index 5ad1e51fb7..f018e35fd0 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java @@ -8,6 +8,7 @@ import io.anuke.kryonet.KryoServer; import io.anuke.mindustry.Mindustry; import io.anuke.mindustry.core.Platform; import io.anuke.mindustry.net.Net; +import io.anuke.ucore.UCore; import io.anuke.ucore.util.OS; public class DesktopLauncher { @@ -20,7 +21,7 @@ public class DesktopLauncher { config.setWindowedMode(960, 540); config.setWindowIcon("sprites/icon.png"); if(OS.isMac) { - config.setPreferencesConfig(System.getProperty("DocumentsDirectory"), FileType.Absolute); + config.setPreferencesConfig(UCore.getProperty("user.home") + "/Library/Application Support/", FileType.Absolute); } Platform.instance = new DesktopPlatform(arg); diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java b/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java index 71c5ec750b..e9fa2400ab 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopPlatform.java @@ -3,17 +3,25 @@ package io.anuke.mindustry.desktop; import club.minnced.discord.rpc.DiscordEventHandlers; import club.minnced.discord.rpc.DiscordRPC; import club.minnced.discord.rpc.DiscordRichPresence; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.utils.Base64Coder; import io.anuke.kryonet.DefaultThreadImpl; import io.anuke.mindustry.core.GameState.State; -import io.anuke.mindustry.core.ThreadHandler.ThreadProvider; import io.anuke.mindustry.core.Platform; +import io.anuke.mindustry.core.ThreadHandler.ThreadProvider; import io.anuke.mindustry.net.Net; import io.anuke.ucore.UCore; import io.anuke.ucore.core.Settings; +import io.anuke.ucore.function.Consumer; import io.anuke.ucore.util.Strings; +import javafx.application.Application; +import javafx.stage.FileChooser; +import javafx.stage.FileChooser.ExtensionFilter; +import javafx.stage.Stage; import javax.swing.*; +import java.io.File; import java.net.NetworkInterface; import java.text.DateFormat; import java.text.NumberFormat; @@ -40,6 +48,19 @@ public class DesktopPlatform extends Platform { } } + @Override + public void showFileChooser(String text, String content, Consumer cons, boolean open, String... filter) { + new Thread(() -> { + FxApp.text = text; + FxApp.cons = cons; + FxApp.filter = filter; + FxApp.open = open; + FxApp.open(); + }){{ + setDaemon(true); + }}.start(); + } + @Override public String format(Date date){ return format.format(date); @@ -139,4 +160,56 @@ public class DesktopPlatform extends Platform { System.arraycopy(bytes, 0, result, 0, bytes.length); return !new String(Base64Coder.encode(result)).equals("AAAAAAAAAOA="); } + + public static class FxApp extends Application{ + static String text; + static Consumer cons; + static String[] filter; + static String content; + static boolean open; + + private static FxApp instance; + + static void open(){ + if(instance == null){ + launch(); + } + ss(); + } + + static void ss(){ + javafx.application.Platform.runLater(() -> instance.show()); + } + + public FxApp(){ + instance = this; + ss(); + } + + @Override + public void start(Stage stage){ + + } + + public void show(){ + for(int i = 0; i < filter.length; i ++){ + filter[i] = "*." + filter[i]; + } + + FileChooser chooser = new FileChooser(); + chooser.setTitle(text); + chooser.getExtensionFilters().add(new ExtensionFilter(content, filter)); + chooser.setInitialDirectory(new File(System.getProperty("user.home"))); + + File file; + if (open) { + file = chooser.showOpenDialog(null); + } else { + file = chooser.showSaveDialog(null); + } + if (file != null) { + cons.accept(Gdx.files.absolute(file.getAbsolutePath())); + } + } + } }