diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 165fca2f8b..ec9d07e948 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -379,6 +379,9 @@ editor.ingame = Edit In-Game editor.publish.workshop = Publish On Workshop editor.newmap = New Map editor.center = Center +editor.search = Search Maps... +editor.filters = Filter Maps +editor.showAll = Show Default Maps workshop = Workshop waves.title = Waves waves.remove = Remove diff --git a/core/src/mindustry/ui/dialogs/MapsDialog.java b/core/src/mindustry/ui/dialogs/MapsDialog.java index ee25c0ae28..cc2fe7009f 100644 --- a/core/src/mindustry/ui/dialogs/MapsDialog.java +++ b/core/src/mindustry/ui/dialogs/MapsDialog.java @@ -2,11 +2,14 @@ package mindustry.ui.dialogs; import arc.*; import arc.graphics.*; +import arc.scene.style.*; import arc.scene.ui.*; import arc.scene.ui.layout.*; +import arc.struct.*; import arc.util.*; import mindustry.*; import mindustry.game.EventType.*; +import mindustry.game.*; import mindustry.gen.*; import mindustry.graphics.*; import mindustry.io.*; @@ -17,6 +20,12 @@ import static mindustry.Vars.*; public class MapsDialog extends BaseDialog{ private BaseDialog dialog; + private String searchString; + private Seq modes = new Seq<>(); + private Table mapTable = new Table(); + private TextField searchField; + + private boolean showAll = Core.settings.getBool("editorShowAllMaps", true); public MapsDialog(){ super("@maps"); @@ -37,8 +46,10 @@ public class MapsDialog extends BaseDialog{ void setup(){ buttons.clearChildren(); + searchString = null; + if(Core.graphics.isPortrait()){ - buttons.button("@back", Icon.left, this::hide).size(210f*2f, 64f).colspan(2); + buttons.button("@back", Icon.left, this::hide).size(210f * 2f, 64f).colspan(2); buttons.row(); }else{ buttons.button("@back", Icon.left, this::hide).size(210f, 64f); @@ -108,26 +119,58 @@ public class MapsDialog extends BaseDialog{ }); }).size(210f, 64f); - cont.clear(); - Table maps = new Table(); - maps.marginRight(24); + rebuildMaps(); - ScrollPane pane = new ScrollPane(maps); + ScrollPane pane = new ScrollPane(mapTable); pane.setFadeScrollBars(false); + Table search = new Table(); + search.image(Icon.zoom); + searchField = search.field("", t -> { + searchString = t.length() > 0 ? t.toLowerCase() : null; + rebuildMaps(); + }).maxTextLength(50).growX().get(); + searchField.setMessageText("@editor.search"); + search.button(Icon.filter, Styles.emptyi, this::showMapFilters); + + cont.add(search).growX(); + cont.row(); + cont.add(pane).uniformX().growY(); + cont.row(); + cont.add(buttons).growX(); + } + + void rebuildMaps(){ + mapTable.clear(); + + mapTable.marginRight(24); + int maxwidth = Math.max((int)(Core.graphics.getWidth() / Scl.scl(230)), 1); float mapsize = 200f; + boolean noMapsShown = true; int i = 0; - for(Map map : Vars.maps.all()){ - if(i % maxwidth == 0){ - maps.row(); + Seq mapList = showAll ? Vars.maps.all() : Vars.maps.customMaps(); + for(Map map : mapList){ + + boolean invalid = false; + for(Gamemode mode : modes){ + invalid |= !mode.valid(map); + } + if(invalid || (searchString != null && !Strings.stripColors(map.name()).toLowerCase().contains(searchString))){ + continue; } - TextButton button = maps.button("", Styles.cleart, () -> showMapInfo(map)).width(mapsize).pad(8).get(); + noMapsShown = false; + + if(i % maxwidth == 0){ + mapTable.row(); + } + + TextButton button = mapTable.button("", Styles.cleart, () -> showMapInfo(map)).width(mapsize).pad(8).get(); button.clearChildren(); button.margin(9); button.add(map.name()).width(mapsize - 18f).center().get().setEllipsis(true); @@ -141,13 +184,41 @@ public class MapsDialog extends BaseDialog{ i++; } - if(Vars.maps.all().size == 0){ - maps.add("@maps.none"); + if(noMapsShown){ + mapTable.add("@maps.none"); } + } - cont.add(buttons).growX(); - cont.row(); - cont.add(pane).uniformX(); + void showMapFilters(){ + dialog = new BaseDialog("@editor.filters"); + dialog.addCloseButton(); + dialog.setFillParent(false); + dialog.cont.table(Tex.button, t -> { + int i = 0; + for(Gamemode mode : Gamemode.all){ + TextureRegionDrawable icon = Vars.ui.getIcon("mode" + Strings.capitalize(mode.name())); + if(Core.atlas.isFound(icon.getRegion())){ + t.button(mode.name(), icon, Styles.clearTogglet, () -> { + if(modes.contains(mode)){ + modes.remove(mode); + }else{ + modes.add(mode); + } + rebuildMaps(); + }).size(150f, 60f).checked(modes.contains(mode)); + if(++i % 3 == 0) t.row(); + } + } + t.row(); + t.button("@editor.showAll", Styles.clearTogglet, () -> { + showAll = !showAll; + Core.settings.put("editorShowAllMaps", showAll); + Core.settings.forceSave(); + rebuildMaps(); + }).checked(b -> showAll).colspan(3).growX().height(40f); + }); + + dialog.show(); } void showMapInfo(Map map){ @@ -213,4 +284,15 @@ public class MapsDialog extends BaseDialog{ dialog.show(); } + + @Override + public Dialog show(){ + super.show(); + + if(Core.app.isDesktop() && searchField != null){ + Core.scene.setKeyboardFocus(searchField); + } + + return this; + } }