Improvements to the Schematics UI (#8605)

* schematics UI improvements

* better edit tags UI

* visual tweaks

* cleanup

inline obsession
cleanup again...
another little bit of cleanup
a little bit of cleanup
minor cleanup
This commit is contained in:
JniTrRny
2023-06-02 22:37:15 +07:00
committed by GitHub
parent bf51a01677
commit c84ec75c53
7 changed files with 234 additions and 207 deletions

View File

@@ -57,6 +57,7 @@ mods.browser.sortstars = Sort by stars
schematic = Schematic schematic = Schematic
schematic.add = Save Schematic... schematic.add = Save Schematic...
schematics = Schematics schematics = Schematics
schematic.search = Search schematics...
schematic.replace = A schematic by that name already exists. Replace it? schematic.replace = A schematic by that name already exists. Replace it?
schematic.exists = A schematic by that name already exists. schematic.exists = A schematic by that name already exists.
schematic.import = Import Schematic... schematic.import = Import Schematic...
@@ -69,7 +70,7 @@ schematic.shareworkshop = Share on Workshop
schematic.flip = [accent][[{0}][]/[accent][[{1}][]: Flip Schematic schematic.flip = [accent][[{0}][]/[accent][[{1}][]: Flip Schematic
schematic.saved = Schematic saved. schematic.saved = Schematic saved.
schematic.delete.confirm = This schematic will be utterly eradicated. schematic.delete.confirm = This schematic will be utterly eradicated.
schematic.rename = Rename Schematic schematic.edit = Edit Schematic
schematic.info = {0}x{1}, {2} blocks schematic.info = {0}x{1}, {2} blocks
schematic.disabled = [scarlet]Schematics disabled[]\nYou are not allowed to use schematics on this [accent]map[] or [accent]server. schematic.disabled = [scarlet]Schematics disabled[]\nYou are not allowed to use schematics on this [accent]map[] or [accent]server.
schematic.tags = Tags: schematic.tags = Tags:
@@ -78,6 +79,7 @@ schematic.addtag = Add Tag
schematic.texttag = Text Tag schematic.texttag = Text Tag
schematic.icontag = Icon Tag schematic.icontag = Icon Tag
schematic.renametag = Rename Tag schematic.renametag = Rename Tag
schematic.tagged = {0} tagged
schematic.tagdelconfirm = Delete this tag completely? schematic.tagdelconfirm = Delete this tag completely?
schematic.tagexists = That tag already exists. schematic.tagexists = That tag already exists.
@@ -463,7 +465,7 @@ waves.sort.begin = Begin
waves.sort.health = Health waves.sort.health = Health
waves.sort.type = Type waves.sort.type = Type
waves.search = Search waves... waves.search = Search waves...
waves.filter.unit = Unit Filter waves.filter = Unit Filter
waves.units.hide = Hide All waves.units.hide = Hide All
waves.units.show = Show All waves.units.show = Show All
@@ -1791,7 +1793,7 @@ hint.launch = Once enough resources are collected, you can [accent]Launch[] by s
hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \uE827 [accent]Map[] in the \uE88C [accent]Menu[]. hint.launch.mobile = Once enough resources are collected, you can [accent]Launch[] by selecting nearby sectors from the \uE827 [accent]Map[] in the \uE88C [accent]Menu[].
hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type. hint.schematicSelect = Hold [accent][[F][] and drag to select blocks to copy and paste.\n\n[accent][[Middle Click][] to copy a single block type.
hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect = Hold [accent][[B][] and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.rebuildSelect.mobile = Select the \ue874 copy button, then tap the \ue80f rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically. hint.rebuildSelect.mobile = Select the \uE874 copy button, then tap the \uE80F rebuild button and drag to select destroyed block plans.\nThis will rebuild them automatically.
hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path. hint.conveyorPathfind = Hold [accent][[L-Ctrl][] while dragging conveyors to automatically generate a path.
hint.conveyorPathfind.mobile = Enable \uE844 [accent]diagonal mode[] and drag conveyors to automatically generate a path. hint.conveyorPathfind.mobile = Enable \uE844 [accent]diagonal mode[] and drag conveyors to automatically generate a path.
hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters. hint.boost = Hold [accent][[L-Shift][] to fly over obstacles with your current unit.\n\nOnly a few ground units have boosters.

View File

@@ -803,7 +803,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
} }
if(i == 0){ if(i == 0){
blockSelection.add("@none.found").color(Color.lightGray).padLeft(54f).padTop(10f); blockSelection.add("@none.found").padLeft(54f).padTop(10f);
} }
} }
} }

View File

@@ -1,9 +1,11 @@
package mindustry.editor; package mindustry.editor;
import arc.*;
import arc.func.*; import arc.func.*;
import arc.scene.ui.*; import arc.scene.ui.*;
import arc.scene.ui.layout.*; import arc.scene.ui.layout.*;
import arc.util.*; import arc.util.*;
import mindustry.gen.*;
import mindustry.maps.*; import mindustry.maps.*;
import mindustry.ui.*; import mindustry.ui.*;
import mindustry.ui.dialogs.*; import mindustry.ui.dialogs.*;
@@ -11,65 +13,60 @@ import mindustry.ui.dialogs.*;
import static mindustry.Vars.*; import static mindustry.Vars.*;
public class MapLoadDialog extends BaseDialog{ public class MapLoadDialog extends BaseDialog{
private Map selected = null; private @Nullable Map selected = null;
public MapLoadDialog(Cons<Map> loader){ public MapLoadDialog(Cons<Map> loader){
super("@editor.loadmap"); super("@editor.loadmap");
shown(this::rebuild); shown(this::rebuild);
hidden(() -> selected = null);
onResize(this::rebuild);
TextButton button = new TextButton("@load"); buttons.defaults().size(210f, 64f);
button.setDisabled(() -> selected == null); buttons.button("@cancel", Icon.cancel, this::hide);
button.clicked(() -> { buttons.button("@load", Icon.ok, () -> {
if(selected != null){ if(selected != null){
loader.get(selected); loader.get(selected);
hide(); hide();
} }
}); }).disabled(b -> selected == null);
buttons.defaults().size(200f, 50f);
buttons.button("@cancel", this::hide);
buttons.add(button);
addCloseListener(); addCloseListener();
makeButtonOverlay();
} }
public void rebuild(){ public void rebuild(){
cont.clear(); cont.clear();
if(maps.all().size > 0){ ButtonGroup<Button> group = new ButtonGroup<>();
selected = maps.all().first();
}
ButtonGroup<TextButton> group = new ButtonGroup<>();
int maxcol = 3;
int i = 0; int i = 0;
int cols = Math.max((int)(Core.graphics.getWidth() / Scl.scl(250f)), 1);
Table table = new Table(); Table table = new Table();
table.defaults().size(200f, 90f).pad(4f); table.defaults().size(250f, 90f).pad(4f);
table.margin(10f); table.margin(10f);
ScrollPane pane = new ScrollPane(table); ScrollPane pane = new ScrollPane(table);
pane.setFadeScrollBars(false); pane.setFadeScrollBars(false);
pane.setScrollingDisabledX(true);
for(Map map : maps.all()){ for(Map map : maps.all()){
table.button(b -> {
b.add(new BorderImage(map.safeTexture(), 2f).setScaling(Scaling.fit)).padLeft(5f).size(16 * 4f);
b.add(map.name()).wrap().grow().labelAlign(Align.center).padLeft(5f);
}, Styles.squareTogglet, () -> selected = map).group(group).checked(b -> selected == map);
TextButton button = new TextButton(map.name(), Styles.flatTogglet); if(++i % cols == 0) table.row();
button.add(new BorderImage(map.safeTexture(), 2f).setScaling(Scaling.fit)).padLeft(5f).size(16 * 4f);
button.getCells().reverse();
button.clicked(() -> selected = map);
button.getLabelCell().grow().left().padLeft(5f);
group.add(button);
table.add(button);
if(++i % maxcol == 0) table.row();
} }
group.uncheckAll();
if(maps.all().isEmpty()){ if(maps.all().isEmpty()){
table.add("@maps.none").center(); table.add("@maps.none").center();
}else{
cont.add("@editor.selectmap");
} }
cont.row(); cont.row();
cont.add(pane).growX(); cont.add(pane);
} }
} }

View File

@@ -33,7 +33,6 @@ public class WaveInfoDialog extends BaseDialog{
private Table table; private Table table;
private int search = -1; private int search = -1;
private UnitType lastType = UnitTypes.dagger;
private @Nullable UnitType filterType; private @Nullable UnitType filterType;
private Sort sort = Sort.begin; private Sort sort = Sort.begin;
private boolean reverseSort = false; private boolean reverseSort = false;
@@ -160,7 +159,7 @@ public class WaveInfoDialog extends BaseDialog{
start = Math.max(search - (displayed / 2) - (displayed % 2), 0); start = Math.max(search - (displayed / 2) - (displayed % 2), 0);
buildGroups(); buildGroups();
}).growX().maxTextLength(8).get().setMessageText("@waves.search"); }).growX().maxTextLength(8).get().setMessageText("@waves.search");
s.button(Icon.units, Styles.emptyi, () -> showUnits(type -> filterType = type, true)).size(46f).tooltip("@waves.filter.unit") s.button(Icon.units, Styles.emptyi, () -> showUnits(type -> filterType = type, true)).size(46f).tooltip("@waves.filter")
.update(b -> b.getStyle().imageUp = filterType != null ? new TextureRegionDrawable(filterType.uiIcon) : Icon.filter); .update(b -> b.getStyle().imageUp = filterType != null ? new TextureRegionDrawable(filterType.uiIcon) : Icon.filter);
}).growX().pad(6f).row(); }).growX().pad(6f).row();
@@ -168,10 +167,7 @@ public class WaveInfoDialog extends BaseDialog{
main.table(t -> { main.table(t -> {
t.button("@add", () -> { t.button("@add", () -> {
SpawnGroup newGroup = new SpawnGroup(lastType); showUnits(type -> groups.add(expandedGroup = new SpawnGroup(type)), false);
groups.add(newGroup);
expandedGroup = newGroup;
showUnits(type -> newGroup.type = lastType = type, false);
buildGroups(); buildGroups();
}).growX().height(70f); }).growX().height(70f);
@@ -233,9 +229,7 @@ public class WaveInfoDialog extends BaseDialog{
b.label(() -> (group.begin + 1) + "").color(Color.lightGray).minWidth(45f).labelAlign(Align.left).left(); b.label(() -> (group.begin + 1) + "").color(Color.lightGray).minWidth(45f).labelAlign(Align.left).left();
b.button(Icon.copySmall, Styles.emptyi, () -> { b.button(Icon.copySmall, Styles.emptyi, () -> {
SpawnGroup copy = group.copy(); groups.insert(groups.indexOf(group) + 1, expandedGroup = group.copy());
expandedGroup = copy;
groups.insert(groups.indexOf(group) + 1, copy);
buildGroups(); buildGroups();
}).pad(-6).size(46f).tooltip("@editor.copy"); }).pad(-6).size(46f).tooltip("@editor.copy");
@@ -244,7 +238,7 @@ public class WaveInfoDialog extends BaseDialog{
Icon.logicSmall, Icon.logicSmall,
Styles.emptyi, () -> showEffects(group)).pad(-6).size(46f).scaling(Scaling.fit).tooltip(group.effect != null ? group.effect.localizedName : "@none"); Styles.emptyi, () -> showEffects(group)).pad(-6).size(46f).scaling(Scaling.fit).tooltip(group.effect != null ? group.effect.localizedName : "@none");
b.button(Icon.unitsSmall, Styles.emptyi, () -> showUnits(type -> group.type = lastType = type, false)).pad(-6).size(46f).tooltip("@stat.unittype"); b.button(Icon.unitsSmall, Styles.emptyi, () -> showUnits(type -> group.type = type, false)).pad(-6).size(46f).tooltip("@stat.unittype");
b.button(Icon.cancel, Styles.emptyi, () -> { b.button(Icon.cancel, Styles.emptyi, () -> {
groups.remove(group); groups.remove(group);
if(expandedGroup == group) expandedGroup = null; if(expandedGroup == group) expandedGroup = null;
@@ -253,9 +247,7 @@ public class WaveInfoDialog extends BaseDialog{
buildGroups(); buildGroups();
}).pad(-6).size(46f).padRight(-12f).tooltip("@waves.remove"); }).pad(-6).size(46f).padRight(-12f).tooltip("@waves.remove");
b.clicked(KeyCode.mouseMiddle, () -> { b.clicked(KeyCode.mouseMiddle, () -> {
SpawnGroup copy = group.copy(); groups.insert(groups.indexOf(group) + 1, expandedGroup = group.copy());
groups.insert(groups.indexOf(group) + 1, copy);
expandedGroup = copy;
buildGroups(); buildGroups();
}); });
}, () -> { }, () -> {
@@ -415,8 +407,7 @@ public class WaveInfoDialog extends BaseDialog{
} }
void showUnits(Cons<UnitType> cons, boolean reset){ void showUnits(Cons<UnitType> cons, boolean reset){
BaseDialog dialog = new BaseDialog(""); BaseDialog dialog = new BaseDialog(reset ? "@waves.filter" : "");
dialog.setFillParent(true);
dialog.cont.pane(p -> { dialog.cont.pane(p -> {
p.defaults().pad(2).fillX(); p.defaults().pad(2).fillX();
if(reset){ if(reset){
@@ -444,40 +435,39 @@ public class WaveInfoDialog extends BaseDialog{
}).margin(12f); }).margin(12f);
if(++i % 3 == 0) p.row(); if(++i % 3 == 0) p.row();
} }
}).growX().scrollX(false); }).scrollX(false);
dialog.addCloseButton(); dialog.addCloseButton();
dialog.show(); dialog.show();
} }
void showEffects(SpawnGroup group){ void showEffects(SpawnGroup group){
BaseDialog dialog = new BaseDialog(""); BaseDialog dialog = new BaseDialog("");
dialog.setFillParent(true);
dialog.cont.pane(p -> { dialog.cont.pane(p -> {
int i = 0; p.defaults().pad(2).fillX();
p.button(t -> {
t.left();
t.image(Icon.none).size(8 * 4).scaling(Scaling.fit).padRight(2f);
t.add("@settings.resetKey");
}, () -> {
group.effect = null;
dialog.hide();
buildGroups();
}).margin(12f);
int i = 1;
for(StatusEffect effect : content.statusEffects()){ for(StatusEffect effect : content.statusEffects()){
if(effect != StatusEffects.none && (effect.isHidden() || effect.reactive)) continue; if(effect.isHidden() || effect.reactive) continue;
p.button(t -> { p.button(t -> {
t.left(); t.left();
if(effect.uiIcon != null && effect != StatusEffects.none){ t.image(effect.uiIcon).size(8 * 4).scaling(Scaling.fit).padRight(2f);
t.image(effect.uiIcon).size(8 * 4).scaling(Scaling.fit).padRight(2f); t.add(effect.localizedName);
}else{
t.image(Icon.none).size(8 * 4).scaling(Scaling.fit).padRight(2f);
}
if(effect != StatusEffects.none){
t.add(effect.localizedName);
}else{
t.add("@settings.resetKey");
}
}, () -> { }, () -> {
group.effect = effect != StatusEffects.none ? effect : null; group.effect = effect;
dialog.hide(); dialog.hide();
buildGroups(); buildGroups();
}).pad(2).margin(12f).fillX(); }).margin(12f);
if(++i % 3 == 0) p.row(); if(++i % 3 == 0) p.row();
} }
}).growX().scrollX(false); }).scrollX(false);
dialog.addCloseButton(); dialog.addCloseButton();
dialog.show(); dialog.show();
} }

View File

@@ -10,7 +10,6 @@ import arc.scene.style.*;
import arc.scene.ui.*; import arc.scene.ui.*;
import arc.scene.ui.layout.*; import arc.scene.ui.layout.*;
import arc.util.*; import arc.util.*;
import mindustry.*;
import mindustry.content.*; import mindustry.content.*;
import mindustry.gen.*; import mindustry.gen.*;
import mindustry.ui.*; import mindustry.ui.*;
@@ -108,9 +107,8 @@ public abstract class FilterOption{
.setRegion(supplier.get() == Blocks.air ? Icon.none.getRegion() : supplier.get().uiIcon)).size(iconSmall), () -> { .setRegion(supplier.get() == Blocks.air ? Icon.none.getRegion() : supplier.get().uiIcon)).size(iconSmall), () -> {
BaseDialog dialog = new BaseDialog("@filter.option." + name); BaseDialog dialog = new BaseDialog("@filter.option." + name);
dialog.cont.pane(t -> { dialog.cont.pane(t -> {
t.margin(14f);
int i = 0; int i = 0;
for(Block block : Vars.content.blocks()){ for(Block block : content.blocks()){
if(!filter.get(block)) continue; if(!filter.get(block)) continue;
t.image(block == Blocks.air ? Icon.none.getRegion() : block.uiIcon).size(iconMed).pad(3).tooltip(block == Blocks.air ? "@none" : block.localizedName).get().clicked(() -> { t.image(block == Blocks.air ? Icon.none.getRegion() : block.uiIcon).size(iconMed).pad(3).tooltip(block == Blocks.air ? "@none" : block.localizedName).get().clicked(() -> {

View File

@@ -15,7 +15,6 @@ import arc.scene.ui.layout.*;
import arc.scene.utils.*; import arc.scene.utils.*;
import arc.struct.*; import arc.struct.*;
import arc.util.*; import arc.util.*;
import mindustry.*;
import mindustry.ctype.*; import mindustry.ctype.*;
import mindustry.game.*; import mindustry.game.*;
import mindustry.gen.*; import mindustry.gen.*;
@@ -48,6 +47,7 @@ public class SchematicsDialog extends BaseDialog{
shouldPause = true; shouldPause = true;
addCloseButton(); addCloseButton();
buttons.button("@schematic.import", Icon.download, this::showImport); buttons.button("@schematic.import", Icon.download, this::showImport);
makeButtonOverlay();
shown(this::setup); shown(this::setup);
onResize(this::setup); onResize(this::setup);
} }
@@ -70,6 +70,7 @@ public class SchematicsDialog extends BaseDialog{
search = res; search = res;
rebuildPane.run(); rebuildPane.run();
}).growX().get(); }).growX().get();
searchField.setMessageText("@schematic.search");
}).fillX().padBottom(4); }).fillX().padBottom(4);
cont.row(); cont.row();
@@ -99,9 +100,7 @@ public class SchematicsDialog extends BaseDialog{
rebuildTags.run(); rebuildTags.run();
}).fillX().height(tagh).scrollY(false); }).fillX().height(tagh).scrollY(false);
in.button(Icon.pencilSmall, () -> { in.button(Icon.pencilSmall, this::showAllTags).size(tagh).pad(2).tooltip("@schematic.edittags");
showAllTags();
}).size(tagh).pad(2).tooltip("@schematic.edittags");
}).height(tagh).fillX(); }).height(tagh).fillX();
cont.row(); cont.row();
@@ -111,7 +110,7 @@ public class SchematicsDialog extends BaseDialog{
t.update(() -> { t.update(() -> {
if(Core.input.keyTap(Binding.chat) && Core.scene.getKeyboardFocus() == searchField && firstSchematic != null){ if(Core.input.keyTap(Binding.chat) && Core.scene.getKeyboardFocus() == searchField && firstSchematic != null){
if(!Vars.state.rules.schematicsAllowed){ if(!state.rules.schematicsAllowed){
ui.showInfo("@schematic.disabled"); ui.showInfo("@schematic.disabled");
}else{ }else{
control.input.useSchematic(firstSchematic); control.input.useSchematic(firstSchematic);
@@ -144,58 +143,14 @@ public class SchematicsDialog extends BaseDialog{
buttons.left(); buttons.left();
buttons.defaults().size(50f); buttons.defaults().size(50f);
ImageButtonStyle style = Styles.clearNonei; ImageButtonStyle style = Styles.emptyi;
buttons.button(Icon.info, style, () -> { buttons.button(Icon.info, style, () -> showInfo(s)).tooltip("@info.title");
showInfo(s); buttons.button(Icon.upload, style, () -> showExport(s)).tooltip("@editor.export");
}); buttons.button(Icon.pencil, style, () -> showEdit(s)).tooltip("@schematic.edit");
buttons.button(Icon.upload, style, () -> {
showExport(s);
});
buttons.button(Icon.pencil, style, () -> {
new BaseDialog("@schematic.rename"){{
setFillParent(true);
cont.margin(30);
cont.add("@schematic.tags").padRight(6f);
cont.table(tags -> buildTags(s, tags, false)).maxWidth(400f).fillX().left().row();
cont.margin(30).add("@name").padRight(6f);
TextField nameField = cont.field(s.name(), null).size(400f, 55f).left().get();
cont.row();
cont.margin(30).add("@editor.description").padRight(6f);
TextField descField = cont.area(s.description(), Styles.areaField, t -> {}).size(400f, 140f).left().get();
Runnable accept = () -> {
s.tags.put("name", nameField.getText());
s.tags.put("description", descField.getText());
s.save();
hide();
rebuildPane.run();
};
buttons.defaults().size(120, 54).pad(4);
buttons.button("@ok", accept).disabled(b -> nameField.getText().isEmpty());
buttons.button("@cancel", this::hide);
keyDown(KeyCode.enter, () -> {
if(!nameField.getText().isEmpty() && Core.scene.getKeyboardFocus() != descField){
accept.run();
}
});
keyDown(KeyCode.escape, this::hide);
keyDown(KeyCode.back, this::hide);
show();
}};
});
if(s.hasSteamID()){ if(s.hasSteamID()){
buttons.button(Icon.link, style, () -> platform.viewListing(s)); buttons.button(Icon.link, style, () -> platform.viewListing(s)).tooltip("@view.workshop");
}else{ }else{
buttons.button(Icon.trash, style, () -> { buttons.button(Icon.trash, style, () -> {
if(s.mod != null){ if(s.mod != null){
@@ -206,9 +161,8 @@ public class SchematicsDialog extends BaseDialog{
rebuildPane.run(); rebuildPane.run();
}); });
} }
}); }).tooltip("@save.delete");
} }
}).growX().height(50f); }).growX().height(50f);
b.row(); b.row();
b.stack(new SchematicImage(s).setScaling(Scaling.fit), new Table(n -> { b.stack(new SchematicImage(s).setScaling(Scaling.fit), new Table(n -> {
@@ -224,7 +178,7 @@ public class SchematicsDialog extends BaseDialog{
if(state.isMenu()){ if(state.isMenu()){
showInfo(s); showInfo(s);
}else{ }else{
if(!Vars.state.rules.schematicsAllowed){ if(!state.rules.schematicsAllowed){
ui.showInfo("@schematic.disabled"); ui.showInfo("@schematic.disabled");
}else{ }else{
control.input.useSchematic(s); control.input.useSchematic(s);
@@ -241,7 +195,11 @@ public class SchematicsDialog extends BaseDialog{
} }
if(firstSchematic == null){ if(firstSchematic == null){
t.add("@none"); if(!searchString.isEmpty() || selectedTags.any()){
t.add("@none.found");
}else{
t.add("@none").color(Color.lightGray);
}
} }
}; };
@@ -254,7 +212,7 @@ public class SchematicsDialog extends BaseDialog{
} }
public void showImport(){ public void showImport(){
BaseDialog dialog = new BaseDialog("@editor.export"); BaseDialog dialog = new BaseDialog("@editor.import");
dialog.cont.pane(p -> { dialog.cont.pane(p -> {
p.margin(10f); p.margin(10f);
p.table(Tex.button, t -> { p.table(Tex.button, t -> {
@@ -307,9 +265,9 @@ public class SchematicsDialog extends BaseDialog{
public void showExport(Schematic s){ public void showExport(Schematic s){
BaseDialog dialog = new BaseDialog("@editor.export"); BaseDialog dialog = new BaseDialog("@editor.export");
dialog.cont.pane(p -> { dialog.cont.pane(p -> {
p.margin(10f); p.margin(10f);
p.table(Tex.button, t -> { p.table(Tex.button, t -> {
TextButtonStyle style = Styles.flatt; TextButtonStyle style = Styles.flatt;
t.defaults().size(280f, 60f).left(); t.defaults().size(280f, 60f).left();
if(steam && !s.hasSteamID()){ if(steam && !s.hasSteamID()){
t.button("@schematic.shareworkshop", Icon.book, style, t.button("@schematic.shareworkshop", Icon.book, style,
@@ -334,6 +292,43 @@ public class SchematicsDialog extends BaseDialog{
dialog.show(); dialog.show();
} }
public void showEdit(Schematic s){
new BaseDialog("@schematic.edit"){{
setFillParent(true);
addCloseListener();
cont.margin(30);
cont.add("@schematic.tags").padRight(6f);
cont.table(tags -> buildTags(s, tags, false)).maxWidth(400f).fillX().left().row();
cont.margin(30).add("@name").padRight(6f);
TextField nameField = cont.field(s.name(), null).size(400f, 55f).left().get();
cont.row();
cont.margin(30).add("@editor.description").padRight(6f);
TextField descField = cont.area(s.description(), Styles.areaField, t -> {}).size(400f, 140f).left().get();
Runnable accept = () -> {
s.tags.put("name", nameField.getText());
s.tags.put("description", descField.getText());
s.save();
hide();
rebuildPane.run();
};
buttons.defaults().size(210f, 64f).pad(4);
buttons.button("@ok", Icon.ok, accept).disabled(b -> nameField.getText().isEmpty());
buttons.button("@cancel", Icon.cancel, this::hide);
keyDown(KeyCode.enter, () -> {
if(!nameField.getText().isEmpty() && Core.scene.getKeyboardFocus() != descField){
accept.run();
}
});
}}.show();
}
//adds all new tags to the global list of tags //adds all new tags to the global list of tags
//alternatively, unknown tags could be discarded on import? //alternatively, unknown tags could be discarded on import?
@@ -406,35 +401,51 @@ public class SchematicsDialog extends BaseDialog{
cont.pane(t -> { cont.pane(t -> {
resized(true, () -> { resized(true, () -> {
t.clearChildren(); t.clearChildren();
t.marginRight(19f); t.marginRight(19f).marginLeft(12f);
t.defaults().size(48f); t.defaults().size(48f);
int cols = (int)Math.min(20, Core.graphics.getWidth() / Scl.scl(52f)); int cols = (int)Math.min(20, Core.graphics.getWidth() / Scl.scl(52f));
int i = 0;
for(String icon : PlanetDialog.defaultIcons){
String out = (char)Iconc.codes.get(icon) + "";
if(tags.contains(out)) continue;
t.button(Icon.icons.get(icon), Styles.flati, iconMed, () -> {
tags.add(out);
tagsChanged();
cons.get(out);
hide();
});
if(++i % cols == 0) t.row();
}
for(ContentType ctype : defaultContentIcons){ for(ContentType ctype : defaultContentIcons){
var all = content.getBy(ctype).<UnlockableContent>as().filter(u -> !u.isHidden() && u.unlockedNow() && u.hasEmoji());
t.row(); t.row();
t.image().colspan(cols).growX().width(Float.NEGATIVE_INFINITY).height(3f).color(Pal.accent); if(all.count(u -> !tags.contains(u.emoji())) > 0) t.image().colspan(cols).growX().width(Float.NEGATIVE_INFINITY).height(3f).color(Pal.accent);
t.row(); t.row();
int i = 0; i = 0;
for(UnlockableContent u : content.getBy(ctype).<UnlockableContent>as()){ for(UnlockableContent u : all){
if(!u.isHidden() && u.unlockedNow() && u.hasEmoji() && !tags.contains(u.emoji())){ if(tags.contains(u.emoji())) continue;
t.button(new TextureRegionDrawable(u.uiIcon), Styles.flati, iconMed, () -> { t.button(new TextureRegionDrawable(u.uiIcon), Styles.flati, iconMed, () -> {
String out = u.emoji() + ""; String out = u.emoji() + "";
tags.add(out); tags.add(out);
tagsChanged(); tagsChanged();
cons.get(out); cons.get(out);
hide(); hide();
}); }).tooltip(u.localizedName);
if(++i % cols == 0) t.row(); if(++i % cols == 0) t.row();
}
} }
} }
}); });
}); }).scrollX(false);
buttons.button("@back", Icon.left, this::hide).size(210f, 64f); buttons.button("@back", Icon.left, this::hide).size(210f, 64f);
}}.show(); }}.show();
} }
@@ -446,66 +457,91 @@ public class SchematicsDialog extends BaseDialog{
dialog.cont.pane(p -> { dialog.cont.pane(p -> {
rebuild[0] = () -> { rebuild[0] = () -> {
p.clearChildren(); p.clearChildren();
p.defaults().fillX().left(); p.margin(12f).defaults().fillX().left();
float sum = 0f; float sum = 0f;
Table current = new Table().left(); Table current = new Table().left();
for(var tag : tags){ for(var tag : tags){
var next = new Table(Tex.button, n -> { var next = new Table(n -> {
n.add(tag).padRight(4); n.table(Tex.pane, move -> {
move.margin(2);
n.add().growX(); //move up
n.defaults().size(30f); move.button(Icon.upOpen, Styles.emptyi, () -> {
int idx = tags.indexOf(tag);
//delete if(idx > 0){
n.button(Icon.cancelSmall, Styles.emptyi, () -> { tags.swap(idx, idx - 1);
ui.showConfirm("@schematic.tagdelconfirm", () -> {
for(Schematic s : schematics.all()){
if(s.labels.any()){
s.labels.remove(tag);
s.save();
}
}
selectedTags.remove(tag);
tags.remove(tag);
tagsChanged();
rebuildPane.run();
rebuild[0].run();
});
});
//rename
n.button(Icon.pencilSmall, Styles.emptyi, () -> {
ui.showTextInput("@schematic.renametag", "@name", tag, result -> {
//same tag, nothing was renamed
if(result.equals(tag)) return;
if(tags.contains(result)){
ui.showInfo("@schematic.tagexists");
}else{
for(Schematic s : schematics.all()){
if(s.labels.any()){
s.labels.replace(tag, result);
s.save();
}
}
selectedTags.replace(tag, result);
tags.replace(tag, result);
tagsChanged(); tagsChanged();
rebuild[0].run(); rebuild[0].run();
} }
}).tooltip("@editor.moveup").row();
//move down
move.button(Icon.downOpen, Styles.emptyi, () -> {
int idx = tags.indexOf(tag);
if(idx < tags.size - 1){
tags.swap(idx, idx + 1);
tagsChanged();
rebuild[0].run();
}
}).tooltip("@editor.movedown");
}).fillY().margin(6f);
n.table(Tex.whiteui, t -> {
t.setColor(Pal.gray);
t.add(tag).left().row();
t.add(Core.bundle.format("schematic.tagged", schematics.all().count(s -> s.labels.contains(tag)))).left()
.update(b -> b.setColor(b.hasMouse() ? Pal.accent : Color.lightGray)).get().clicked(() -> {
dialog.hide();
selectedTags.clear().add(tag);
rebuildTags.run();
rebuildPane.run();
}); });
}); }).growX().fillY().margin(8f);
//move
n.button(Icon.upSmall, Styles.emptyi, () -> { n.table(Tex.pane, b -> {
int idx = tags.indexOf(tag); b.margin(2);
if(idx > 0){
tags.swap(idx, idx - 1); //rename tag
tagsChanged(); b.button(Icon.pencil, Styles.emptyi, () -> {
rebuild[0].run(); ui.showTextInput("@schematic.renametag", "@name", tag, result -> {
} //same tag, nothing was renamed
}); if(result.equals(tag)) return;
if(tags.contains(result)){
ui.showInfo("@schematic.tagexists");
}else{
for(Schematic s : schematics.all()){
if(s.labels.any()){
s.labels.replace(tag, result);
s.save();
}
}
selectedTags.replace(tag, result);
tags.replace(tag, result);
tagsChanged();
rebuild[0].run();
}
});
}).tooltip("@schematic.renametag").row();
//delete tag
b.button(Icon.trash, Styles.emptyi, () -> {
ui.showConfirm("@schematic.tagdelconfirm", () -> {
for(Schematic s : schematics.all()){
if(s.labels.any()){
s.labels.remove(tag);
s.save();
}
}
selectedTags.remove(tag);
tags.remove(tag);
tagsChanged();
rebuildPane.run();
rebuild[0].run();
});
}).tooltip("@save.delete");
}).fillY().margin(6f);
}); });
next.pack(); next.pack();
@@ -515,10 +551,10 @@ public class SchematicsDialog extends BaseDialog{
p.add(current).row(); p.add(current).row();
current = new Table(); current = new Table();
current.left(); current.left();
current.add(next).height(tagh).pad(2); current.add(next).minWidth(240).pad(4);
sum = 0; sum = 0;
}else{ }else{
current.add(next).height(tagh).pad(2); current.add(next).minWidth(240).pad(4);
} }
sum += w; sum += w;
@@ -538,7 +574,7 @@ public class SchematicsDialog extends BaseDialog{
}; };
resized(true, rebuild[0]); resized(true, rebuild[0]);
}); }).scrollX(false);
dialog.show(); dialog.show();
} }
@@ -574,6 +610,7 @@ public class SchematicsDialog extends BaseDialog{
dialog.addCloseButton(); dialog.addCloseButton();
dialog.cont.pane(p -> resized(true, () -> { dialog.cont.pane(p -> resized(true, () -> {
p.clearChildren(); p.clearChildren();
p.defaults().fillX().left();
float sum = 0f; float sum = 0f;
Table current = new Table().left(); Table current = new Table().left();
@@ -704,19 +741,16 @@ public class SchematicsDialog extends BaseDialog{
SchematicInfoDialog(){ SchematicInfoDialog(){
super(""); super("");
setFillParent(true); setFillParent(true);
addCloseButton(); addCloseListener();
} }
public void show(Schematic schem){ public void show(Schematic schem){
cont.clear(); cont.clear();
title.setText("[[" + Core.bundle.get("schematic") + "] " +schem.name()); title.setText("[[" + Core.bundle.get("schematic") + "] " +schem.name());
cont.add(Core.bundle.format("schematic.info", schem.width, schem.height, schem.tiles.size)).color(Color.lightGray); cont.add(Core.bundle.format("schematic.info", schem.width, schem.height, schem.tiles.size)).color(Color.lightGray).row();
cont.row();
cont.table(tags -> buildTags(schem, tags)).fillX().left().row(); cont.table(tags -> buildTags(schem, tags)).fillX().left().row();
cont.row(); cont.add(new SchematicImage(schem)).maxSize(800f).row();
cont.add(new SchematicImage(schem)).maxSize(800f);
cont.row();
ItemSeq arr = schem.requirements(); ItemSeq arr = schem.requirements();
cont.table(r -> { cont.table(r -> {
@@ -755,6 +789,12 @@ public class SchematicsDialog extends BaseDialog{
}); });
} }
buttons.clearChildren();
buttons.defaults().size(210f, 64f);
buttons.button("@back", Icon.left, this::hide);
buttons.button("@editor.export", Icon.upload, () -> showExport(schem));
buttons.button("@schematic.edit", Icon.edit, () -> showEdit(schem));
show(); show();
} }
} }

View File

@@ -87,9 +87,9 @@ public class ItemSelection{
if(rowCount > rows * 1.5f){ if(rowCount > rows * 1.5f){
main.table(s -> { main.table(s -> {
s.image(Icon.zoom).padLeft(4f); s.image(Icon.zoom).padLeft(4f);
search = s.field(null, text -> rebuild.run()).width(40 * columns).padBottom(4).left().growX().get(); search = s.field(null, text -> rebuild.run()).padBottom(4).left().growX().get();
search.setMessageText("@players.search"); search.setMessageText("@players.search");
}).row(); }).fillX().row();
} }
ScrollPane pane = new ScrollPane(cont, Styles.smallPane); ScrollPane pane = new ScrollPane(cont, Styles.smallPane);
@@ -103,7 +103,7 @@ public class ItemSelection{
} }
pane.setOverscroll(false, false); pane.setOverscroll(false, false);
main.add(pane).growX().maxHeight(40 * rows); main.add(pane).maxHeight(40 * rows);
table.top().add(main); table.top().add(main);
} }
} }