From efb218653b451ab79af3e28450b1af544cf6631e Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 23 Jul 2026 15:52:44 -0400 Subject: [PATCH 1/7] Logic field layout autowrap --- core/src/mindustry/logic/LCanvas.java | 16 +++++++++------- core/src/mindustry/logic/LStatement.java | 10 +++++++--- core/src/mindustry/logic/LStatements.java | 5 +++++ gradle.properties | 2 +- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/core/src/mindustry/logic/LCanvas.java b/core/src/mindustry/logic/LCanvas.java index 320b8e59ca..3ae98e724f 100644 --- a/core/src/mindustry/logic/LCanvas.java +++ b/core/src/mindustry/logic/LCanvas.java @@ -101,7 +101,7 @@ public class LCanvas extends Table{ } public void rebuild(){ - targetWidth = useRows() ? 400f : 900f; + targetWidth = Math.max(400f, Core.graphics.getWidth() / Scl.scl(1f) * 0.95f - Scl.scl(80f)); float s = pane != null ? pane.getVisualScrollY() : 0f; String toLoad = statements != null ? save() : null; @@ -492,12 +492,14 @@ public class LCanvas extends Table{ row(); - table(t -> { - t.left(); - t.marginLeft(4); - t.setColor(color); - st.build(t); - }).pad(4).padTop(2).left().grow(); + Table t = st.useWrapping() ? new WrapTable() : new Table(); + + t.left(); + t.marginLeft(4); + t.setColor(color); + st.build(t); + + add(t).pad(4).padTop(2).left().grow(); marginBottom(7); } diff --git a/core/src/mindustry/logic/LStatement.java b/core/src/mindustry/logic/LStatement.java index b92e00fcf3..a6483e71de 100644 --- a/core/src/mindustry/logic/LStatement.java +++ b/core/src/mindustry/logic/LStatement.java @@ -60,6 +60,10 @@ public abstract class LStatement{ return read.size == 0 ? null : read.first(); } + public boolean useWrapping(){ + return true; + } + public boolean hidden(){ return false; } @@ -122,12 +126,12 @@ public abstract class LStatement{ protected Cell field(Table table, String value, Cons setter){ return table.field(value, Styles.nodeField, s -> setter.get(sanitize(s))) - .size(144f, 40f).pad(2f).color(table.color); + .size(180f, 40f).pad(2f).color(table.color); } protected Cell fields(Table table, String desc, String value, Cons setter){ table.add(desc).padLeft(10).left().self(this::param); - return field(table, value, setter).width(85f).padRight(10).left(); + return field(table, value, setter).width(100f).padRight(10).left(); } /** Puts the text and field in one table, taking up one cell. */ @@ -136,7 +140,7 @@ public abstract class LStatement{ table.table(t -> { t.setColor(table.color); t.add(desc).padLeft(10).left().self(this::param); - result[0] = field(t, value, setter).width(85f).padRight(10).left(); + result[0] = field(t, value, setter).width(100f).padRight(10).left(); }); return result[0]; diff --git a/core/src/mindustry/logic/LStatements.java b/core/src/mindustry/logic/LStatements.java index cd107e4b03..357c626daf 100644 --- a/core/src/mindustry/logic/LStatements.java +++ b/core/src/mindustry/logic/LStatements.java @@ -994,6 +994,11 @@ public class LStatements{ public ConditionOp op = ConditionOp.notEqual; public String value = "x", compare = "false"; + @Override + public boolean useWrapping(){ + return false; + } + @Override public void build(Table table){ table.add("if ").padLeft(4); diff --git a/gradle.properties b/gradle.properties index ed78c070f2..86571c00e9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,4 +26,4 @@ org.gradle.caching=true org.gradle.internal.http.socketTimeout=100000 org.gradle.internal.http.connectionTimeout=100000 android.enableR8.fullMode=false -archash=18fd1e15f0 +archash=d82584374c From 16ee499f75894b453f277be8ecad35dd7f62d000 Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 7 Sep 2026 13:55:49 -0400 Subject: [PATCH 2/7] Longer fields, width cap --- core/src/mindustry/logic/LCanvas.java | 2 +- core/src/mindustry/logic/LStatement.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/mindustry/logic/LCanvas.java b/core/src/mindustry/logic/LCanvas.java index 18259c102f..c92b57b2ef 100644 --- a/core/src/mindustry/logic/LCanvas.java +++ b/core/src/mindustry/logic/LCanvas.java @@ -101,7 +101,7 @@ public class LCanvas extends Table{ } public void rebuild(){ - targetWidth = Math.max(400f, Core.graphics.getWidth() / Scl.scl(1f) * 0.95f - Scl.scl(80f)); + targetWidth = Core.graphics.isPortrait() ? 400f : Mathf.clamp(Core.graphics.getWidth() / Scl.scl(1f) * 0.95f - Scl.scl(80f), 400f, 1200f); float s = pane != null ? pane.getVisualScrollY() : 0f; String toLoad = statements != null ? save() : null; diff --git a/core/src/mindustry/logic/LStatement.java b/core/src/mindustry/logic/LStatement.java index 6dbf0ef545..cb3942c986 100644 --- a/core/src/mindustry/logic/LStatement.java +++ b/core/src/mindustry/logic/LStatement.java @@ -164,7 +164,7 @@ public abstract class LStatement{ protected Cell fields(Table table, String desc, String value, Cons setter){ table.add(desc).padLeft(10).left().self(this::param); - return field(table, value, setter).width(100f).padRight(10).left(); + return field(table, value, setter).width(180f).padRight(10).left(); } /** Puts the text and field in one table, taking up one cell. */ @@ -173,7 +173,7 @@ public abstract class LStatement{ table.table(t -> { t.setColor(table.color); t.add(desc).padLeft(10).left().self(this::param); - result[0] = field(t, value, setter).width(100f).padRight(10).left(); + result[0] = field(t, value, setter).width(180f).padRight(10).left(); }); return result[0]; From 80a2eef23937a81d42656cb3c69e418cf506723f Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 7 Sep 2026 14:17:48 -0400 Subject: [PATCH 3/7] Removed row() --- core/src/mindustry/logic/LStatements.java | 134 ++-------------------- 1 file changed, 7 insertions(+), 127 deletions(-) diff --git a/core/src/mindustry/logic/LStatements.java b/core/src/mindustry/logic/LStatements.java index fc08eda652..7f2cc14966 100644 --- a/core/src/mindustry/logic/LStatements.java +++ b/core/src/mindustry/logic/LStatements.java @@ -73,8 +73,6 @@ public class LStatements{ field(table, target, str -> target = str); - row(table); - table.add(bundle("at")); field(table, address, str -> address = str); @@ -105,8 +103,6 @@ public class LStatements{ field(table, target, str -> target = str); - row(table); - table.add(bundle("at")); field(table, address, str -> address = str); @@ -162,7 +158,6 @@ public class LStatements{ }, Styles.logict, () -> {}).size(90, 40).color(table.color).left().padLeft(2); if(type != GraphicsType.stroke){ - row(table); } table.table(s -> { @@ -460,8 +455,6 @@ public class LStatements{ field(table, target, v -> target = v); - row(table); - //Q: why don't you just use arrays for this? //A: arrays aren't as easy to serialize so the code generator doesn't handle them int c = 0; @@ -469,7 +462,6 @@ public class LStatements{ fields(table, bundle(type.params[i]), i == 0 ? p1 : i == 1 ? p2 : i == 2 ? p3 : p4, i == 0 ? v -> p1 = v : i == 1 ? v -> p2 = v : i == 2 ? v -> p3 = v : v -> p4 = v); - if(++c % 2 == 0) row(table); } } @@ -499,7 +491,6 @@ public class LStatements{ fields(table, radar, v -> radar = v); - row(table); } for(int i = 0; i < 3; i++){ @@ -514,18 +505,12 @@ public class LStatements{ if(fi == 0) target1 = t; else if(fi == 1) target2 = t; else target3 = t; }, 2, cell -> cell.size(100, 50))); }, Styles.logict, () -> {}).size(90, 40).color(table.color).left().padLeft(2); - - if(i == 1){ - row(table); - } } table.add(bundle("order")).self(this::param); fields(table, sortOrder, v -> sortOrder = v); - table.row(); - table.add(bundle("sort")).self(this::param); table.button(b -> { @@ -569,8 +554,6 @@ public class LStatements{ table.add(" = "); - row(table); - tfield = field(table, type, str -> type = str).padRight(0f).get(); table.button(b -> { @@ -731,13 +714,10 @@ public class LStatements{ field(table, a, str -> a = str); }else{ - row(table); - //"function"-type operations have the name at the left and arguments on the right if(op.func){ if(LCanvas.useRows()){ table.left(); - table.row(); table.table(c -> { c.color.set(category().color); c.left(); @@ -815,7 +795,6 @@ public class LStatements{ }, comp0, str -> comp0 = str, comp1, str -> comp1 = str); }).left(); - table.row(); table.table(t -> { t.setColor(table.color); @@ -887,8 +866,6 @@ public class LStatements{ table.add(bundle("-lookup")); - row(table); - table.button(b -> { b.label(() -> bundle(type)); b.clicked(() -> showSelect(b, GlobalVars.lookableContent, type, o -> { @@ -923,8 +900,6 @@ public class LStatements{ table.add(" = "); table.add(bundle("pack")); - row(table); - fields(table, r, str -> r = str); fields(table, g, str -> g = str); fields(table, b, str -> b = str); @@ -953,8 +928,6 @@ public class LStatements{ fields(table, b, str -> b = str); fields(table, a, str -> a = str); - row(table); - table.add(" = "); table.add(bundle("unpack")); @@ -1142,29 +1115,21 @@ public class LStatements{ table.button(b -> { b.label(() -> bundle(type)); b.clicked(() -> showSelect(b, Structs.filter(LUnitControl.class, LUnitControl.all, t -> - t == LUnitControl.build ? state.rules.logicUnitBuild : - t == LUnitControl.deconstruct ? state.rules.logicUnitDeconstruct : - true + t == LUnitControl.build ? state.rules.logicUnitBuild : + t == LUnitControl.deconstruct ? state.rules.logicUnitDeconstruct : + true ), type, t -> { type = t; rebuild(table); }, 2, cell -> cell.size(120, 50))); }, Styles.logict, () -> {}).size(120, 40).color(table.color).left().padLeft(2); - row(table); - //Q: why don't you just use arrays for this? //A: arrays aren't as easy to serialize so the code generator doesn't handle them int c = 0; for(int i = 0; i < type.params.length; i++){ fields(table, bundle(type.params[i]), i == 0 ? p1 : i == 1 ? p2 : i == 2 ? p3 : i == 3 ? p4 : p5, i == 0 ? v -> p1 = v : i == 1 ? v -> p2 = v : i == 2 ? v -> p3 = v : i == 3 ? v -> p4 = v : v -> p5 = v).width(100f); - - if(++c % 2 == 0) row(table); - - if(i == 3){ - table.row(); - } } } @@ -1230,19 +1195,15 @@ public class LStatements{ switch(locate){ case building -> { - row(table); table.add(bundle("group")).left().self(this::param); table.button(b -> { b.label(() -> bundle(flag)); b.clicked(() -> showSelect(b, BlockFlag.allLogic, flag, t -> flag = t, 2, cell -> cell.size(110, 50))); }, Styles.logict, () -> {}).size(110, 40).color(table.color).left().padLeft(2); - row(table); - table.add(bundle("enemy")).left().self(this::param); fields(table, enemy, str -> enemy = str); - table.row(); } case ore -> { @@ -1275,11 +1236,9 @@ public class LStatements{ }); - table.row(); } case spawn, damaged -> { - table.row(); } } @@ -1289,8 +1248,6 @@ public class LStatements{ table.add(bundle("outY")).left().self(this::param); fields(table, outY, str -> outY = str); - row(table); - table.add(bundle("found")).left().self(this::param); fields(table, outFound, str -> outFound = str); @@ -1337,13 +1294,9 @@ public class LStatements{ fields(table, bundle("team"), team, str -> team = str); - row(table); - fields(table, "x", x, str -> x = str); fields(table, "y", y, str -> y = str); - table.row(); - if(shape == QueryShape.circle){ fields(table, bundle("radius"), w, str -> w = str); }else{ @@ -1380,8 +1333,6 @@ public class LStatements{ table.add(" = "); table.add(bundle("get")); - row(table); - table.button(b -> { b.label(() -> bundle(layer)); b.clicked(() -> showSelect(b, TileLayer.all, layer, o -> layer = o)); @@ -1432,23 +1383,17 @@ public class LStatements{ })); }, Styles.logict, () -> {}).size(64f, 40f).pad(4f).color(table.color); - row(table); - table.add(bundle("at")); fields(table, x, str -> x = str); table.add(", "); fields(table, y, str -> y = str); - row(table); - table.add(bundle("to")); fields(table, block, str -> block = str); if(layer == TileLayer.block){ - row(table); - table.add(bundle("team")); fields(table, team, str -> team = str); @@ -1484,16 +1429,12 @@ public class LStatements{ table.add(bundle("-spawn")); field(table, type, str -> type = str).colspan(!LCanvas.useRows() ? 1 : 2); - row(table); - table.add(bundle("at")); fields(table, x, str -> x = str); table.add(", "); fields(table, y, str -> y = str); - table.row(); - if(!LCanvas.useRows()){ table.add(); } @@ -1504,8 +1445,6 @@ public class LStatements{ table.add(bundle("rot")); fields(table, rotation, str -> rotation = str).left(); - row(table); - table.add(bundle("effect")); fields(table, effect, str -> effect = str).left(); } @@ -1536,23 +1475,16 @@ public class LStatements{ table.add(bundle("-bullet")); - row(table); - fields(table, bundle("from"), from, str -> from = str); fields(table, bundle("index"), index, str -> index = str); - row(table); fields(table, "x", x, str -> x = str); fields(table, "y", y, str -> y = str); - table.row(); fields(table, bundle("rotation"), rotation, str -> rotation = str); fields(table, bundle("team"), team, str -> team = str); - row(table); fields(table, bundle("owner"), owner, str -> owner = str); fields(table, bundle("damage"), damage, str -> damage = str); - table.row(); fields(table, bundle("velocityScl"), velocityScl, str -> velocityScl = str); fields(table, bundle("lifeScl"), lifeScl, str -> lifeScl = str); - row(table); fields(table, bundle("aimX"), aimX, str -> aimX = str); fields(table, bundle("aimY"), aimY, str -> aimY = str); } @@ -1565,9 +1497,9 @@ public class LStatements{ @Override public LInstruction build(LAssembler builder){ return new SpawnBulletI( - builder.var(result), builder.var(from), builder.var(index), builder.var(x), builder.var(y), builder.var(rotation), - builder.var(team), builder.var(owner), builder.var(damage), builder.var(velocityScl), builder.var(lifeScl), - builder.var(aimX), builder.var(aimY) + builder.var(result), builder.var(from), builder.var(index), builder.var(x), builder.var(y), builder.var(rotation), + builder.var(team), builder.var(owner), builder.var(damage), builder.var(velocityScl), builder.var(lifeScl), + builder.var(aimX), builder.var(aimY) ); } @@ -1611,15 +1543,11 @@ public class LStatements{ })); }, Styles.logict, () -> {}).size(40f).padLeft(-2f).color(table.color); - row(table); - table.add(bundle(clear ? "from" : "to")).left(); fields(table, unit, str -> unit = str).left(); if(!clear && !isPermanent()){ - row(table); - table.add(bundle("for")).left(); fields(table, duration, str -> duration = str).left(); @@ -1665,8 +1593,6 @@ public class LStatements{ table.add(" = "); table.add(bundle("weather")); - row(table); - tfield = field(table, weather, str -> weather = str).padRight(0f).get(); table.button(b -> { @@ -1819,11 +1745,8 @@ public class LStatements{ case mapArea -> { table.add(" = "); - row(table); - fields(table, "x", p1, s -> p1 = s); fields(table, "y", p2, s -> p2 = s); - row(table); fields(table, "w", p3, s -> p3 = s); fields(table, "h", p4, s -> p4 = s); } @@ -1834,7 +1757,6 @@ public class LStatements{ fields(table, bundle("of"), p1, s -> p1 = s); table.add(" = "); - row(table); field(table, value, s -> value = s); } case ban, unban -> { @@ -1894,8 +1816,6 @@ public class LStatements{ table.add(bundle("sec")); } } - row(table); - table.add(bundle("success")); fields(table, outSuccess, str -> outSuccess = str); } @@ -1948,8 +1868,6 @@ public class LStatements{ table.add(" y "); fields(table, p2, str -> p2 = str); - row(table); - table.add(bundle("speed")); fields(table, p3, str -> p3 = str); } @@ -2004,12 +1922,8 @@ public class LStatements{ EffectEntry entry = LogicFx.get(type); - row(table); - fields(table, "x", x, str -> x = str); fields(table, "y", y, str -> y = str); - row(table); - if(entry != null){ if(entry.color){ fields(table, bundle("color"), color, str -> color = str).width(120f); @@ -2020,8 +1934,6 @@ public class LStatements{ }); } - row(table); - if(entry.size || entry.rotate){ fields(table, bundle(entry.size ? "size" : "rotation"), sizerot, str -> sizerot = str); } @@ -2056,16 +1968,12 @@ public class LStatements{ public void build(Table table){ fields(table, bundle("team"), team, str -> team = str); fields(table, "x", x, str -> x = str); - row(table); fields(table, "y", y, str -> y = str); fields(table, bundle("radius"), radius, str -> radius = str); - table.row(); fields(table, bundle("damage"), damage, str -> damage = str); fields(table, bundle("air"), air, str -> air = str); - row(table); fields(table, bundle("ground"), ground, str -> ground = str); fields(table, bundle("pierce"), pierce, str -> pierce = str); - table.row(); fields(table, bundle("effect"), effect, str -> effect = str); } @@ -2130,27 +2038,19 @@ public class LStatements{ }, 2, c -> c.width(150f))); }, Styles.logict, () -> {}).size(160f, 40f).margin(5f).pad(4f).color(table.color); - row(table); - fields(table, bundle("team"), team, s -> team = s); if(type != FetchType.coreCount && type != FetchType.playerCount && type != FetchType.unitCount && type != FetchType.buildCount){ table.add(" # "); - row(table); - fields(table, index, i -> index = i); } if(type == FetchType.buildCount || type == FetchType.build){ - row(table); - fields(table, bundle("block"), extra, i -> extra = i); } if(type == FetchType.unitCount || type == FetchType.unit){ - row(table); - fields(table, bundle("unit"), extra, i -> extra = i); } } @@ -2386,14 +2286,10 @@ public class LStatements{ })); }, Styles.logict, () -> {}).size(40f).padLeft(-1).color(table.color); - row(table); - table.add(bundle("of")).self(this::param); field(table, of, str -> of = str).colspan(2); - row(table); - table.add(bundle("to")); field(table, value, str -> value = str).colspan(2); @@ -2434,8 +2330,6 @@ public class LStatements{ build(table); }).size(160f, 40f).pad(4f).color(table.color); - row(table); - field(table, id, str -> id = str).padRight(0f).get(); table.button(b -> { @@ -2443,13 +2337,9 @@ public class LStatements{ b.clicked(() -> showSoundSelect(b, table)); }, Styles.logict, () -> {}).size(40).color(table.color).left().padLeft(-1); - row(table); - fieldst(table, bundle("volume"), volume, str -> volume = str); fieldst(table, bundle("pitch"), pitch, str -> pitch = str); - table.row(); - if(positional){ fieldst(table, "x", x, str -> x = str); @@ -2458,8 +2348,6 @@ public class LStatements{ fieldst(table, bundle("pan"), pan, str -> pan = str); } - table.row(); - fieldst(table, bundle("limit"), limit, str -> limit = str); } @@ -2682,8 +2570,6 @@ public class LStatements{ }, 3, cell -> cell.size(140, 50))); }, Styles.logict, () -> {}).size(190, 40).color(table.color).left().padLeft(2); - row(table); - fieldst(table, bundle("of-id-"), id, str -> id = str); //Q: why don't you just use arrays for this? @@ -2730,8 +2616,6 @@ public class LStatements{ } }); - if(i == 0) row(table); - if(i == 2) table.row(); } } @@ -2770,14 +2654,10 @@ public class LStatements{ fieldst(table, "id", id, str -> id = str); - row(table); - fieldst(table, "x", x, v -> x = v); fieldst(table, "y", y, v -> y = v); - row(table); - fieldst(table, bundle("replace"), replace, v -> replace = v); } @@ -2821,4 +2701,4 @@ public class LStatements{ return LCategory.world; } } -} +} \ No newline at end of file From 7e2d57247d61e21ec2d7d749c07f9671851bec1e Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 7 Sep 2026 14:25:41 -0400 Subject: [PATCH 4/7] minor tweaks --- core/assets/bundles/bundle.properties | 2 +- core/src/mindustry/logic/LCanvas.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 07fa97b3a0..d2924c7395 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -3579,7 +3579,7 @@ name.token.music = music name.token.interrupt = interrupt name.token.all = All name.token.beams = Beams -name.token.block = Block +name.token.block = block name.token.charge = Charge name.token.environment = Environment name.token.explosions = Explosions diff --git a/core/src/mindustry/logic/LCanvas.java b/core/src/mindustry/logic/LCanvas.java index c92b57b2ef..c0b151296b 100644 --- a/core/src/mindustry/logic/LCanvas.java +++ b/core/src/mindustry/logic/LCanvas.java @@ -497,6 +497,7 @@ public class LCanvas extends Table{ t.left(); t.marginLeft(4); t.setColor(color); + if(st.useWrapping()) t.marginRight(4f); st.build(t); add(t).pad(4).padTop(2).left().grow(); From 3787b6308cae172ed8efc1f5d9b7d95aeac0a14b Mon Sep 17 00:00:00 2001 From: Anuken Date: Mon, 7 Sep 2026 19:32:15 -0400 Subject: [PATCH 5/7] minor tweaks --- core/src/mindustry/logic/LStatement.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/src/mindustry/logic/LStatement.java b/core/src/mindustry/logic/LStatement.java index cb3942c986..1cf3094978 100644 --- a/core/src/mindustry/logic/LStatement.java +++ b/core/src/mindustry/logic/LStatement.java @@ -163,8 +163,12 @@ public abstract class LStatement{ } protected Cell fields(Table table, String desc, String value, Cons setter){ - table.add(desc).padLeft(10).left().self(this::param); - return field(table, value, setter).width(180f).padRight(10).left(); + Table sub = new Table(); + sub.setColor(table.color); + + table.add(sub); + sub.add(desc).padLeft(10).left().self(this::param); + return field(sub, value, setter).width(180f).padRight(10).left(); } /** Puts the text and field in one table, taking up one cell. */ From 6407a48973e66c32c34721d83df8117509694462 Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 9 Sep 2026 11:20:20 -0400 Subject: [PATCH 6/7] Major cleanup of layout --- core/assets/bundles/bundle.properties | 20 +- core/src/mindustry/logic/LCanvas.java | 6 +- core/src/mindustry/logic/LStatement.java | 37 +- core/src/mindustry/logic/LStatements.java | 405 ++++++++++------------ 4 files changed, 215 insertions(+), 253 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index d2924c7395..99aca5ed7c 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -3409,7 +3409,7 @@ tilelayer.label.ore = ore tilelayer.label.block = block tilelayer.label.building = building -name.token.Jump = jump +name.token.jump = Jump name.token.color = color name.token.width = width name.token.height = height @@ -3493,7 +3493,7 @@ name.token.volume = volume name.token.pitch = pitch name.token.pan = pan name.token.limit = limit -name.token.of-id- = of id\# +name.token.id = id \# name.token.replace = replace? name.token.for = for name.token.success = success @@ -3577,13 +3577,13 @@ name.token.wave = wave name.token.bubble = bubble name.token.music = music name.token.interrupt = interrupt -name.token.all = All -name.token.beams = Beams +name.token.all = all +name.token.beams = beams name.token.block = block -name.token.charge = Charge -name.token.environment = Environment -name.token.explosions = Explosions -name.token.loops = Loops -name.token.movement = Movement -name.token.shoot = Shoot +name.token.charge = charge +name.token.environment = environment +name.token.explosions = explosions +name.token.loops = loops +name.token.movement = movement +name.token.shoot = shoot name.token.ui = UI diff --git a/core/src/mindustry/logic/LCanvas.java b/core/src/mindustry/logic/LCanvas.java index c0b151296b..fb4a02521b 100644 --- a/core/src/mindustry/logic/LCanvas.java +++ b/core/src/mindustry/logic/LCanvas.java @@ -100,8 +100,12 @@ public class LCanvas extends Table{ } } + public static float getTargetWidth(){ + return useRows() ? 400f : Mathf.clamp(Core.graphics.getWidth() / Scl.scl(1f) * 0.95f - Scl.scl(80f), 400f, 1200f); + } + public void rebuild(){ - targetWidth = Core.graphics.isPortrait() ? 400f : Mathf.clamp(Core.graphics.getWidth() / Scl.scl(1f) * 0.95f - Scl.scl(80f), 400f, 1200f); + targetWidth = getTargetWidth(); float s = pane != null ? pane.getVisualScrollY() : 0f; String toLoad = statements != null ? save() : null; diff --git a/core/src/mindustry/logic/LStatement.java b/core/src/mindustry/logic/LStatement.java index 1cf3094978..d18cb32d09 100644 --- a/core/src/mindustry/logic/LStatement.java +++ b/core/src/mindustry/logic/LStatement.java @@ -163,24 +163,27 @@ public abstract class LStatement{ } protected Cell fields(Table table, String desc, String value, Cons setter){ - Table sub = new Table(); - sub.setColor(table.color); - - table.add(sub); - sub.add(desc).padLeft(10).left().self(this::param); - return field(sub, value, setter).width(180f).padRight(10).left(); + return fields(table, desc, LCanvas.useRows(), value, setter); } - /** Puts the text and field in one table, taking up one cell. */ - protected Cell fieldst(Table table, String desc, String value, Cons setter){ - Cell[] result = {null}; - table.table(t -> { - t.setColor(table.color); - t.add(desc).padLeft(10).left().self(this::param); - result[0] = field(t, value, setter).width(180f).padRight(10).left(); - }); + protected Cell fields(Table table, String value, Cons setter){ + return field(table, value, setter).width(180f); + } - return result[0]; + protected Cell fields(Table table, String desc, boolean nameAfterField, String value, Cons setter){ + Table sub = new Table(); + sub.setColor(table.color); + table.add(sub); + float width = 180f; + + if(nameAfterField){ + var result = field(sub, value, setter).width(width).padLeft(8f).padRight(4f).left(); + sub.add(desc).padRight(5f).self(this::param); + return result; + }else{ + sub.add(desc).padLeft(10).self(this::param); + return field(sub, value, setter).width(width).padRight(10).left(); + } } /** Adds color edit button */ @@ -200,10 +203,6 @@ public abstract class LStatement{ }, Styles.logict, () -> {}).size(40f).padLeft(-11).color(table.color); } - protected Cell fields(Table table, String value, Cons setter){ - return field(table, value, setter).width(85f); - } - protected void row(Table table){ if(LCanvas.useRows()){ table.row(); diff --git a/core/src/mindustry/logic/LStatements.java b/core/src/mindustry/logic/LStatements.java index 7f2cc14966..8231b4460f 100644 --- a/core/src/mindustry/logic/LStatements.java +++ b/core/src/mindustry/logic/LStatements.java @@ -157,100 +157,94 @@ public class LStatements{ }, 2, cell -> cell.size(100, 50))); }, Styles.logict, () -> {}).size(90, 40).color(table.color).left().padLeft(2); - if(type != GraphicsType.stroke){ - } + if(useRows()) table.add().width(200f); - table.table(s -> { - s.left(); - s.setColor(table.color); - - switch(type){ - case clear -> { - fields(s, "r", x, v -> x = v); - fields(s, "g", y, v -> y = v); - fields(s, "b", p1, v -> p1 = v); - } - case color -> { - fields(s, "r", x, v -> x = v); - fields(s, "g", y, v -> y = v); - fields(s, "b", p1, v -> p1 = v); - row(s); - fields(s, "a", p2, v -> p2 = v); - } - case col -> { - fields(s, bundle("color"), x, v -> x = v).width(144f); - col(s, x, res -> { - x = "%" + res.toString().substring(0, res.a >= 1f ? 6 : 8); - build(table); - }); - } - case stroke -> { - s.add().width(4); - fields(s, x, v -> x = v); - } - case line -> { - fields(s, "x", x, v -> x = v); - fields(s, "y", y, v -> y = v); - row(s); - fields(s, "x2", p1, v -> p1 = v); - fields(s, "y2", p2, v -> p2 = v); - } - case rect, lineRect -> { - fields(s, "x", x, v -> x = v); - fields(s, "y", y, v -> y = v); - row(s); - fields(s, bundle("width"), p1, v -> p1 = v); - fields(s, bundle("height"), p2, v -> p2 = v); - } - case poly, linePoly -> { - fields(s, "x", x, v -> x = v); - fields(s, "y", y, v -> y = v); - row(s); - fields(s, bundle("sides"), p1, v -> p1 = v); - fields(s, bundle("radius"), p2, v -> p2 = v); - row(s); - fields(s, bundle("rotation"), p3, v -> p3 = v); - } - case triangle -> { - fields(s, "x", x, v -> x = v); - fields(s, "y", y, v -> y = v); - row(s); - fields(s, "x2", p1, v -> p1 = v); - fields(s, "y2", p2, v -> p2 = v); - row(s); - fields(s, "x3", p3, v -> p3 = v); - fields(s, "y3", p4, v -> p4 = v); - } - case image -> { - fields(s, "x", x, v -> x = v); - fields(s, "y", y, v -> y = v); - row(s); - fields(s, bundle("image"), p1, v -> p1 = v); - fields(s, bundle("size"), p2, v -> p2 = v); - row(s); - fields(s, bundle("rotation"), p3, v -> p3 = v); - } - case print -> { - fields(s, "x", x, v -> x = v); - fields(s, "y", y, v -> y = v); - - row(s); - - fields(s, bundle("align"), p1, v -> p1 = v).width(170f); - fieldAlignSelect(s, () -> p1, v -> { - p1 = v; - rebuild(table); - }, true, true); - } - case translate, scale -> { - fields(s, "x", x, v -> x = v); - fields(s, "y", y, v -> y = v); - } - case rotate -> { - fields(s, bundle("degrees"), p1, v -> p1 = v); - } + switch(type){ + case clear -> { + fields(table, "r", x, v -> x = v); + fields(table, "g", y, v -> y = v); + fields(table, "b", p1, v -> p1 = v); } - }).expand().left(); + case color -> { + fields(table, "r", x, v -> x = v); + fields(table, "g", y, v -> y = v); + fields(table, "b", p1, v -> p1 = v); + row(table); + fields(table, "a", p2, v -> p2 = v); + } + case col -> { + fields(table, bundle("color"), x, v -> x = v).width(144f); + col(table, x, res -> { + x = "%" + res.toString().substring(0, res.a >= 1f ? 6 : 8); + build(table); + }); + } + case stroke -> { + table.add().width(4); + fields(table, x, v -> x = v); + } + case line -> { + fields(table, "x", x, v -> x = v); + fields(table, "y", y, v -> y = v); + row(table); + fields(table, "x2", p1, v -> p1 = v); + fields(table, "y2", p2, v -> p2 = v); + } + case rect, lineRect -> { + fields(table, "x", x, v -> x = v); + fields(table, "y", y, v -> y = v); + row(table); + fields(table, bundle("width"), p1, v -> p1 = v); + fields(table, bundle("height"), p2, v -> p2 = v); + } + case poly, linePoly -> { + fields(table, "x", x, v -> x = v); + fields(table, "y", y, v -> y = v); + row(table); + fields(table, bundle("sides"), p1, v -> p1 = v); + fields(table, bundle("radius"), p2, v -> p2 = v); + row(table); + fields(table, bundle("rotation"), p3, v -> p3 = v); + } + case triangle -> { + fields(table, "x", x, v -> x = v); + fields(table, "y", y, v -> y = v); + row(table); + fields(table, "x2", p1, v -> p1 = v); + fields(table, "y2", p2, v -> p2 = v); + row(table); + fields(table, "x3", p3, v -> p3 = v); + fields(table, "y3", p4, v -> p4 = v); + } + case image -> { + fields(table, "x", x, v -> x = v); + fields(table, "y", y, v -> y = v); + row(table); + fields(table, bundle("image"), p1, v -> p1 = v); + fields(table, bundle("size"), p2, v -> p2 = v); + row(table); + fields(table, bundle("rotation"), p3, v -> p3 = v); + } + case print -> { + fields(table, "x", x, v -> x = v); + fields(table, "y", y, v -> y = v); + + row(table); + + fields(table, bundle("align"), p1, v -> p1 = v).width(170f); + fieldAlignSelect(table, () -> p1, v -> { + p1 = v; + rebuild(table); + }, true, true); + } + case translate, scale -> { + fields(table, "x", x, v -> x = v); + fields(table, "y", y, v -> y = v); + } + case rotate -> { + fields(table, bundle("degrees"), p1, v -> p1 = v); + } + } } @Override @@ -343,7 +337,7 @@ public class LStatements{ @Override public void build(Table table){ - field(table, value, str -> value = str).width(0f).growX().padRight(3); + field(table, value, str -> value = str).width(LCanvas.getTargetWidth() - Scl.scl(20f)).padRight(3); } @Override @@ -1015,15 +1009,16 @@ public class LStatements{ } public static void addOp(LStatement st, Table t, ConditionOp op, Cons getter, String comp0, Cons set0, String comp1, Cons set2){ - if(op != ConditionOp.always) st.field(t, comp0, set0); + float w = !useRows() ? 180f : 140f; + + if(op != ConditionOp.always) st.field(t, comp0, set0).width(w); t.button(b -> { - b.add(st.selectTranslate(op.symbol)); - b.clicked(() -> st.showSelect(b, ConditionOp.all, op, getter)); - }, Styles.logict, () -> { - }).size(op == ConditionOp.always ? 80f : 48f, 40f).pad(4f).color(t.color); + b.add(selectTranslate(op.symbol)); + b.clicked(() -> st.showSelect(b, ConditionOp.all, op, getter, 3, c -> c.width(95f))); + }, Styles.logict, () -> {}).size(op == ConditionOp.always ? 90f : 48f, 40f).pad(4f).color(t.color); - if(op != ConditionOp.always) st.field(t, comp1, set2); + if(op != ConditionOp.always) st.field(t, comp1, set2).width(w); } //elements need separate conversion logic @@ -1102,16 +1097,8 @@ public class LStatements{ @Override public void build(Table table){ - rebuild(table); - } - - void rebuild(Table table){ table.clearChildren(); - table.left(); - - table.add(" "); - table.button(b -> { b.label(() -> bundle(type)); b.clicked(() -> showSelect(b, Structs.filter(LUnitControl.class, LUnitControl.all, t -> @@ -1120,16 +1107,16 @@ public class LStatements{ true ), type, t -> { type = t; - rebuild(table); + build(table); }, 2, cell -> cell.size(120, 50))); - }, Styles.logict, () -> {}).size(120, 40).color(table.color).left().padLeft(2); + }, Styles.logict, () -> {}).size(180, 40).color(table.color).left().padLeft(2); + + if(useRows()) table.add().width(200f); //Q: why don't you just use arrays for this? //A: arrays aren't as easy to serialize so the code generator doesn't handle them - int c = 0; for(int i = 0; i < type.params.length; i++){ - - fields(table, bundle(type.params[i]), i == 0 ? p1 : i == 1 ? p2 : i == 2 ? p3 : i == 3 ? p4 : p5, i == 0 ? v -> p1 = v : i == 1 ? v -> p2 = v : i == 2 ? v -> p3 = v : i == 3 ? v -> p4 = v : v -> p5 = v).width(100f); + fields(table, bundle(type.params[i]), i == 0 ? p1 : i == 1 ? p2 : i == 2 ? p3 : i == 3 ? p4 : p5, i == 0 ? v -> p1 = v : i == 1 ? v -> p2 = v : i == 2 ? v -> p3 = v : i == 3 ? v -> p4 = v : v -> p5 = v); } } @@ -1177,10 +1164,6 @@ public class LStatements{ @Override public void build(Table table){ - rebuild(table); - } - - void rebuild(Table table){ table.clearChildren(); table.add(bundle("find")).left().self(this::param); @@ -1189,7 +1172,7 @@ public class LStatements{ b.label(() -> bundle(locate)); b.clicked(() -> showSelect(b, LLocate.all, locate, t -> { locate = t; - rebuild(table); + build(table); }, 2, cell -> cell.size(110, 50))); }, Styles.logict, () -> {}).size(110, 40).color(table.color).left().padLeft(2); @@ -1198,20 +1181,17 @@ public class LStatements{ table.add(bundle("group")).left().self(this::param); table.button(b -> { b.label(() -> bundle(flag)); - b.clicked(() -> showSelect(b, BlockFlag.allLogic, flag, t -> flag = t, 2, cell -> cell.size(110, 50))); - }, Styles.logict, () -> {}).size(110, 40).color(table.color).left().padLeft(2); - table.add(bundle("enemy")).left().self(this::param); - - fields(table, enemy, str -> enemy = str); + b.clicked(() -> showSelect(b, BlockFlag.allLogic, flag, t -> flag = t, 2, cell -> cell.size(120, 50))); + }, Styles.logict, () -> {}).size(120, 40).color(table.color).left().padLeft(2); + fields(table, "enemy", enemy, str -> enemy = str); } case ore -> { - table.add(bundle("ore")).left().self(this::param); table.table(ts -> { ts.color.set(table.color); - fields(ts, ore, str -> ore = str); + fields(ts, "ore", ore, str -> ore = str); ts.button(b -> { b.image(Icon.pencilSmall); @@ -1224,7 +1204,7 @@ public class LStatements{ if(!item.unlockedNow()) continue; i.button(new TextureRegionDrawable(item.uiIcon), Styles.flati, iconSmall, () -> { ore = "@" + item.name; - rebuild(table); + build(table); hide.run(); }).size(40f); @@ -1242,18 +1222,14 @@ public class LStatements{ } } - table.add(bundle("outX")).left().self(this::param); - fields(table, outX, str -> outX = str); + fields(table, "outX", outX, str -> outX = str); - table.add(bundle("outY")).left().self(this::param); - fields(table, outY, str -> outY = str); + fields(table, "outY", outY, str -> outY = str); - table.add(bundle("found")).left().self(this::param); - fields(table, outFound, str -> outFound = str); + fields(table, "found", outFound, str -> outFound = str); if(locate != LLocate.ore){ - table.add(bundle("building")).left().self(this::param); - fields(table, outBuild, str -> outBuild = str); + fields(table, "building", outBuild, str -> outBuild = str); } } @@ -1290,7 +1266,7 @@ public class LStatements{ type = o; build(table); })); - }, Styles.logict, () -> {}).size(64f, 40f).pad(4f).color(table.color); + }, Styles.logict, () -> {}).size(100f, 40f).pad(4f).color(table.color); fields(table, bundle("team"), team, str -> team = str); @@ -1336,7 +1312,7 @@ public class LStatements{ table.button(b -> { b.label(() -> bundle(layer)); b.clicked(() -> showSelect(b, TileLayer.all, layer, o -> layer = o)); - }, Styles.logict, () -> {}).size(64f, 40f).pad(4f).color(table.color); + }, Styles.logict, () -> {}).size(120f, 40f).pad(4f).color(table.color); table.add(bundle("at")); @@ -1424,29 +1400,19 @@ public class LStatements{ @Override public void build(Table table){ - fields(table, result, str -> result = str); + fields(table, "-spawn", result, str -> result = str); - table.add(bundle("-spawn")); - field(table, type, str -> type = str).colspan(!LCanvas.useRows() ? 1 : 2); + fields(table, "type", type, str -> type = str); - table.add(bundle("at")); - fields(table, x, str -> x = str); + fields(table, "x", x, str -> x = str); - table.add(", "); - fields(table, y, str -> y = str); + fields(table, "y", y, str -> y = str); - if(!LCanvas.useRows()){ - table.add(); - } + fields(table, "team", team, str -> team = str); - table.add(bundle("team")); - field(table, team, str -> team = str); + fields(table, "angle", rotation, str -> rotation = str); - table.add(bundle("rot")); - fields(table, rotation, str -> rotation = str).left(); - - table.add(bundle("effect")); - fields(table, effect, str -> effect = str).left(); + fields(table, "effect", effect, str -> effect = str); } @Override @@ -1471,9 +1437,7 @@ public class LStatements{ @Override public void build(Table table){ - fields(table, result, str -> result = str); - - table.add(bundle("-bullet")); + fields(table, "-bullet", result, str -> result = str); fields(table, bundle("from"), from, str -> from = str); fields(table, bundle("index"), index, str -> index = str); @@ -1641,9 +1605,6 @@ public class LStatements{ @Override public void build(Table table){ - table.add(bundle("set")); - table.add(bundle("weather")); - tfield = field(table, weather, str -> weather = str).padRight(0f).get(); table.button(b -> { @@ -1795,29 +1756,24 @@ public class LStatements{ @Override public void build(Table table){ - rebuild(table); - } - - void rebuild(Table table){ table.clearChildren(); table.button(b -> { b.label(() -> bundle(type)).growX().wrap().labelAlign(Align.center); b.clicked(() -> showSelect(b, MessageType.all, type, o -> { type = o; - rebuild(table); + build(table); }, 2, c -> c.width(150f))); }, Styles.logict, () -> {}).size(160f, 40f).padLeft(2).color(table.color); + if(useRows()) table.add().width(200f); + switch(type){ case announce, toast -> { - table.add(bundle("for")); - fields(table, duration, str -> duration = str); - table.add(bundle("sec")); + fields(table, "duration", duration, str -> duration = str); } } - table.add(bundle("success")); - fields(table, outSuccess, str -> outSuccess = str); + fields(table, "success", outSuccess, str -> outSuccess = str); } @Override @@ -2330,25 +2286,32 @@ public class LStatements{ build(table); }).size(160f, 40f).pad(4f).color(table.color); - field(table, id, str -> id = str).padRight(0f).get(); + table.table(t -> { + t.setColor(table.color); + field(t, id, str -> id = str).padRight(0f).get(); - table.button(b -> { - b.image(Icon.pencilSmall); - b.clicked(() -> showSoundSelect(b, table)); - }, Styles.logict, () -> {}).size(40).color(table.color).left().padLeft(-1); + t.button(b -> { + b.image(Icon.pencilSmall); + b.clicked(() -> showSoundSelect(b, table)); + }, Styles.logict, () -> {}).size(40).color(table.color).left().padLeft(-1); + }); - fieldst(table, bundle("volume"), volume, str -> volume = str); - fieldst(table, bundle("pitch"), pitch, str -> pitch = str); + String desc2 = bundle("volume"); + fields(table, desc2, volume, str3 -> volume = str3); + String desc1 = bundle("pitch"); + fields(table, desc1, pitch, str2 -> pitch = str2); if(positional){ - fieldst(table, "x", x, str -> x = str); + fields(table, "x", x, str1 -> x = str1); - fieldst(table, "y", y, str -> y = str); + fields(table, "y", y, str -> y = str); }else{ - fieldst(table, bundle("pan"), pan, str -> pan = str); + String desc = bundle("pan"); + fields(table, desc, pan, str -> pan = str); } - fieldst(table, bundle("limit"), limit, str -> limit = str); + String desc = bundle("limit"); + fields(table, desc, limit, str -> limit = str); } @Override @@ -2570,52 +2533,47 @@ public class LStatements{ }, 3, cell -> cell.size(140, 50))); }, Styles.logict, () -> {}).size(190, 40).color(table.color).left().padLeft(2); - fieldst(table, bundle("of-id-"), id, str -> id = str); + String desc = bundle("id"); + fields(table, desc, id, str -> id = str); //Q: why don't you just use arrays for this? //A: arrays aren't as easy to serialize so the code generator doesn't handle them for(int f = 0; f < type.params.length; f++){ - int i = f; - table.table(t -> { - t.setColor(table.color); + String value = f == 0 ? p1 : f == 1 ? p2 : p3; + Cons setter = f == 0 ? v -> p1 = v : f == 1 ? v -> p2 = v : v -> p3 = v; - String value = i == 0 ? p1 : i == 1 ? p2 : p3; - Cons setter = i == 0 ? v -> p1 = v : i == 1 ? v -> p2 = v : v -> p3 = v; - - fields(t, bundle(type.params[i]), value, setter).width(100f); - - if(type == LMarkerControl.color || (type == LMarkerControl.colori && i == 1)){ - col(t, value, res -> { - setter.get("%" + res.toString().substring(0, res.a >= 1f ? 6 : 8)); - build(table); - }); - }else if(type == LMarkerControl.drawLayer){ - t.button(b -> { - b.image(Icon.pencilSmall); - b.clicked(() -> showSelectTable(b, (o, hide) -> { - o.row(); - o.table(s -> { - s.left(); - for(var field : Layer.class.getFields()){ - float layer = Reflect.get(field); - s.button(field.getName() + " = " + layer, Styles.logicTogglet, () -> { - p1 = Float.toString(layer); - rebuild(table); - hide.run(); - }).size(240f, 40f).row(); - } - }).width(240f).left(); - })); - }, Styles.logict, () -> {}).size(40f).padLeft(-11).color(table.color); - }else if(type == LMarkerControl.textAlign || type == LMarkerControl.lineAlign){ - fieldAlignSelect(t, () -> p1, v -> { - p1 = v; - rebuild(table); - }, true, type != LMarkerControl.lineAlign); - } - }); + fields(table, bundle(type.params[f]), value, setter); + if(type == LMarkerControl.color || (type == LMarkerControl.colori && f == 1)){ + col(table, value, res -> { + setter.get("%" + res.toString().substring(0, res.a >= 1f ? 6 : 8)); + build(table); + }); + }else if(type == LMarkerControl.drawLayer){ + table.button(b -> { + b.image(Icon.pencilSmall); + b.clicked(() -> showSelectTable(b, (o, hide) -> { + o.row(); + o.table(s -> { + s.left(); + for(var field : Layer.class.getFields()){ + float layer = Reflect.get(field); + s.button(field.getName() + " = " + layer, Styles.logicTogglet, () -> { + p1 = Float.toString(layer); + rebuild(table); + hide.run(); + }).size(240f, 40f).row(); + } + }).width(240f).left(); + })); + }, Styles.logict, () -> {}).size(40f).padLeft(-11).color(table.color); + }else if(type == LMarkerControl.textAlign || type == LMarkerControl.lineAlign){ + fieldAlignSelect(table, () -> p1, v -> { + p1 = v; + rebuild(table); + }, true, type != LMarkerControl.lineAlign); + } } } @@ -2652,13 +2610,14 @@ public class LStatements{ }, 2, cell -> cell.size(160, 50))); }, Styles.logict, () -> {}).size(190, 40).color(table.color).left().padLeft(2); - fieldst(table, "id", id, str -> id = str); + fields(table, "id", id, str -> id = str); - fieldst(table, "x", x, v -> x = v); + fields(table, "x", x, v2 -> x = v2); - fieldst(table, "y", y, v -> y = v); + fields(table, "y", y, v1 -> y = v1); - fieldst(table, bundle("replace"), replace, v -> replace = v); + String desc = bundle("replace"); + fields(table, desc, replace, v -> replace = v); } @Override @@ -2683,7 +2642,7 @@ public class LStatements{ @Override public void build(Table table){ - field(table, value, str -> value = str).width(0f).growX().padRight(3); + field(table, value, str -> value = str).width(LCanvas.getTargetWidth() - Scl.scl(20f)).padRight(3); } @Override From 2837f2cad298ddedd9b8e9dca8c78a273f9d43ae Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 9 Sep 2026 12:43:04 -0400 Subject: [PATCH 7/7] More layout fixes --- core/assets/bundles/bundle.properties | 7 +- core/assets/bundles/bundle_be.properties | 2 +- core/assets/bundles/bundle_bg.properties | 2 +- core/assets/bundles/bundle_ca.properties | 2 +- core/assets/bundles/bundle_cs.properties | 2 +- core/assets/bundles/bundle_da.properties | 2 +- core/assets/bundles/bundle_de.properties | 2 +- core/assets/bundles/bundle_et.properties | 2 +- core/assets/bundles/bundle_eu.properties | 2 +- core/assets/bundles/bundle_fi.properties | 2 +- core/assets/bundles/bundle_fil.properties | 2 +- core/assets/bundles/bundle_fr.properties | 2 +- core/assets/bundles/bundle_it.properties | 2 +- core/assets/bundles/bundle_ja.properties | 2 +- core/assets/bundles/bundle_ko.properties | 2 +- core/assets/bundles/bundle_lt.properties | 2 +- core/assets/bundles/bundle_nl.properties | 2 +- core/assets/bundles/bundle_nl_BE.properties | 2 +- core/assets/bundles/bundle_pl.properties | 2 +- core/assets/bundles/bundle_pt_BR.properties | 2 +- core/assets/bundles/bundle_pt_PT.properties | 2 +- core/assets/bundles/bundle_ro.properties | 2 +- core/assets/bundles/bundle_ru.properties | 2 +- core/assets/bundles/bundle_sr.properties | 2 +- core/assets/bundles/bundle_sv.properties | 2 +- core/assets/bundles/bundle_th.properties | 2 +- core/assets/bundles/bundle_tk.properties | 2 +- core/assets/bundles/bundle_tr.properties | 2 +- core/assets/bundles/bundle_uk_UA.properties | 2 +- core/assets/bundles/bundle_vi.properties | 2 +- core/assets/bundles/bundle_zh_TW.properties | 2 +- core/src/mindustry/logic/LCanvas.java | 10 +- core/src/mindustry/logic/LStatement.java | 15 +- core/src/mindustry/logic/LStatements.java | 350 +++++++++----------- core/src/mindustry/logic/LogicDialog.java | 6 +- 35 files changed, 197 insertions(+), 251 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 99aca5ed7c..56b30eac5b 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -3201,8 +3201,8 @@ cutsceneaction.label.pan = pan cutsceneaction.label.zoom = zoom cutsceneaction.label.stop = stop cutsceneaction.label.shake = shake -cutsceneaction.label.gethud = get Hud -cutsceneaction.label.sethud = set Hud +cutsceneaction.label.gethud = get HUD +cutsceneaction.label.sethud = set HUD fetchtype.label.unit = unit fetchtype.label.player = player fetchtype.label.core = core @@ -3385,7 +3385,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast @@ -3482,6 +3482,7 @@ name.token.natural = natural name.token.speed = speed name.token.level = level name.token.duration = duration +name.token.seconds = seconds name.token.shown = shown name.token.data = data name.token.effect = effect diff --git a/core/assets/bundles/bundle_be.properties b/core/assets/bundles/bundle_be.properties index af3328c5d9..8d3409bc12 100644 --- a/core/assets/bundles/bundle_be.properties +++ b/core/assets/bundles/bundle_be.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_bg.properties b/core/assets/bundles/bundle_bg.properties index 62ca0d4f33..3e13dc6548 100644 --- a/core/assets/bundles/bundle_bg.properties +++ b/core/assets/bundles/bundle_bg.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_ca.properties b/core/assets/bundles/bundle_ca.properties index a008039229..02e38ca9a4 100644 --- a/core/assets/bundles/bundle_ca.properties +++ b/core/assets/bundles/bundle_ca.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_cs.properties b/core/assets/bundles/bundle_cs.properties index 0a2395e855..b4f83b9bfc 100644 --- a/core/assets/bundles/bundle_cs.properties +++ b/core/assets/bundles/bundle_cs.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_da.properties b/core/assets/bundles/bundle_da.properties index 5fc0ba071d..22ba789714 100644 --- a/core/assets/bundles/bundle_da.properties +++ b/core/assets/bundles/bundle_da.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_de.properties b/core/assets/bundles/bundle_de.properties index f76d365a51..8384528854 100644 --- a/core/assets/bundles/bundle_de.properties +++ b/core/assets/bundles/bundle_de.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_et.properties b/core/assets/bundles/bundle_et.properties index d7f6b37c2e..38ebb3fe37 100644 --- a/core/assets/bundles/bundle_et.properties +++ b/core/assets/bundles/bundle_et.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_eu.properties b/core/assets/bundles/bundle_eu.properties index 495d265669..67f86a5ac1 100644 --- a/core/assets/bundles/bundle_eu.properties +++ b/core/assets/bundles/bundle_eu.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_fi.properties b/core/assets/bundles/bundle_fi.properties index 4d69ebafa3..b8a6417954 100644 --- a/core/assets/bundles/bundle_fi.properties +++ b/core/assets/bundles/bundle_fi.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_fil.properties b/core/assets/bundles/bundle_fil.properties index 6d8038eb6c..5adcd2fc98 100644 --- a/core/assets/bundles/bundle_fil.properties +++ b/core/assets/bundles/bundle_fil.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_fr.properties b/core/assets/bundles/bundle_fr.properties index 7e46563b4d..9bb33ced15 100644 --- a/core/assets/bundles/bundle_fr.properties +++ b/core/assets/bundles/bundle_fr.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_it.properties b/core/assets/bundles/bundle_it.properties index 82979926a6..b98985210d 100644 --- a/core/assets/bundles/bundle_it.properties +++ b/core/assets/bundles/bundle_it.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_ja.properties b/core/assets/bundles/bundle_ja.properties index c7e76ab607..0f36bf13d7 100644 --- a/core/assets/bundles/bundle_ja.properties +++ b/core/assets/bundles/bundle_ja.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_ko.properties b/core/assets/bundles/bundle_ko.properties index 64772574ef..7f6c853269 100644 --- a/core/assets/bundles/bundle_ko.properties +++ b/core/assets/bundles/bundle_ko.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_lt.properties b/core/assets/bundles/bundle_lt.properties index b5c5695c36..338bb116de 100644 --- a/core/assets/bundles/bundle_lt.properties +++ b/core/assets/bundles/bundle_lt.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_nl.properties b/core/assets/bundles/bundle_nl.properties index 1cd5ae5f71..7201a5bb10 100644 --- a/core/assets/bundles/bundle_nl.properties +++ b/core/assets/bundles/bundle_nl.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_nl_BE.properties b/core/assets/bundles/bundle_nl_BE.properties index d583eb65d5..b8be9ce2de 100644 --- a/core/assets/bundles/bundle_nl_BE.properties +++ b/core/assets/bundles/bundle_nl_BE.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_pl.properties b/core/assets/bundles/bundle_pl.properties index c2328b6497..49877de561 100644 --- a/core/assets/bundles/bundle_pl.properties +++ b/core/assets/bundles/bundle_pl.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_pt_BR.properties b/core/assets/bundles/bundle_pt_BR.properties index e0bea24c59..8b4449c406 100644 --- a/core/assets/bundles/bundle_pt_BR.properties +++ b/core/assets/bundles/bundle_pt_BR.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_pt_PT.properties b/core/assets/bundles/bundle_pt_PT.properties index 54758e5e85..e413a7fd4c 100644 --- a/core/assets/bundles/bundle_pt_PT.properties +++ b/core/assets/bundles/bundle_pt_PT.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_ro.properties b/core/assets/bundles/bundle_ro.properties index c7d8ee30ec..254a3bc7b2 100644 --- a/core/assets/bundles/bundle_ro.properties +++ b/core/assets/bundles/bundle_ro.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_ru.properties b/core/assets/bundles/bundle_ru.properties index b4c96a58dd..79619ccd28 100644 --- a/core/assets/bundles/bundle_ru.properties +++ b/core/assets/bundles/bundle_ru.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_sr.properties b/core/assets/bundles/bundle_sr.properties index 6faf52a70a..fab7ec720e 100644 --- a/core/assets/bundles/bundle_sr.properties +++ b/core/assets/bundles/bundle_sr.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_sv.properties b/core/assets/bundles/bundle_sv.properties index df410c762b..7e1b47a89d 100644 --- a/core/assets/bundles/bundle_sv.properties +++ b/core/assets/bundles/bundle_sv.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_th.properties b/core/assets/bundles/bundle_th.properties index 2596c3c944..21285f78a1 100644 --- a/core/assets/bundles/bundle_th.properties +++ b/core/assets/bundles/bundle_th.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_tk.properties b/core/assets/bundles/bundle_tk.properties index dccf3708e7..69f86b1d59 100644 --- a/core/assets/bundles/bundle_tk.properties +++ b/core/assets/bundles/bundle_tk.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_tr.properties b/core/assets/bundles/bundle_tr.properties index 65a684ce1c..586308c062 100644 --- a/core/assets/bundles/bundle_tr.properties +++ b/core/assets/bundles/bundle_tr.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_uk_UA.properties b/core/assets/bundles/bundle_uk_UA.properties index 304715f04a..274b023b67 100644 --- a/core/assets/bundles/bundle_uk_UA.properties +++ b/core/assets/bundles/bundle_uk_UA.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_vi.properties b/core/assets/bundles/bundle_vi.properties index 4cc89fffed..00057e99e6 100644 --- a/core/assets/bundles/bundle_vi.properties +++ b/core/assets/bundles/bundle_vi.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/assets/bundles/bundle_zh_TW.properties b/core/assets/bundles/bundle_zh_TW.properties index 6c81f3f38c..f7f47c757c 100644 --- a/core/assets/bundles/bundle_zh_TW.properties +++ b/core/assets/bundles/bundle_zh_TW.properties @@ -3380,7 +3380,7 @@ lunitcontrol.label.build = build block lunitcontrol.label.getblock = get block lunitcontrol.label.deconstruct = deconstruct lunitcontrol.label.within = within? -lunitcontrol.label.boost = boost? +lunitcontrol.label.boost = boost messagetype.label.notify = notify messagetype.label.announce = announce messagetype.label.toast = toast diff --git a/core/src/mindustry/logic/LCanvas.java b/core/src/mindustry/logic/LCanvas.java index fb4a02521b..767af6ba1d 100644 --- a/core/src/mindustry/logic/LCanvas.java +++ b/core/src/mindustry/logic/LCanvas.java @@ -60,10 +60,14 @@ public class LCanvas extends Table{ } /** @return if statement elements should have rows. */ - public static boolean useRows(){ + public static boolean isCompact(){ return Core.graphics.getWidth() < Scl.scl(900f) * 1.2f; } + public static float getTargetWidth(){ + return isCompact() ? 410f : Mathf.clamp(Core.graphics.getWidth() / Scl.scl(1f) * 0.95f - Scl.scl(80f), 400f, 1200f); + } + public static void tooltip(Cell cell, String key){ String lkey = key.toLowerCase().replace(" ", ""); if(Core.bundle.has(lkey)){ @@ -100,10 +104,6 @@ public class LCanvas extends Table{ } } - public static float getTargetWidth(){ - return useRows() ? 400f : Mathf.clamp(Core.graphics.getWidth() / Scl.scl(1f) * 0.95f - Scl.scl(80f), 400f, 1200f); - } - public void rebuild(){ targetWidth = getTargetWidth(); float s = pane != null ? pane.getVisualScrollY() : 0f; diff --git a/core/src/mindustry/logic/LStatement.java b/core/src/mindustry/logic/LStatement.java index d18cb32d09..5aabe6e411 100644 --- a/core/src/mindustry/logic/LStatement.java +++ b/core/src/mindustry/logic/LStatement.java @@ -163,7 +163,7 @@ public abstract class LStatement{ } protected Cell fields(Table table, String desc, String value, Cons setter){ - return fields(table, desc, LCanvas.useRows(), value, setter); + return fields(table, desc, LCanvas.isCompact(), value, setter); } protected Cell fields(Table table, String value, Cons setter){ @@ -175,13 +175,14 @@ public abstract class LStatement{ sub.setColor(table.color); table.add(sub); float width = 180f; + String text = bundle(desc); if(nameAfterField){ - var result = field(sub, value, setter).width(width).padLeft(8f).padRight(4f).left(); - sub.add(desc).padRight(5f).self(this::param); + var result = field(sub, value, setter).width(width).padRight(4f).left(); + sub.add(text).padRight(12f).self(this::param); return result; }else{ - sub.add(desc).padLeft(10).self(this::param); + sub.add(text).padLeft(10).self(this::param); return field(sub, value, setter).width(width).padRight(10).left(); } } @@ -203,12 +204,6 @@ public abstract class LStatement{ }, Styles.logict, () -> {}).size(40f).padLeft(-11).color(table.color); } - protected void row(Table table){ - if(LCanvas.useRows()){ - table.row(); - } - } - protected void showSelect(Button b, T[] values, T current, Cons getter, int cols, Cons sizer){ showSelectTable(b, (t, hide) -> { ButtonGroup