Core database content icon click support

This commit is contained in:
Anuken 2024-06-19 16:56:20 -04:00
parent 4f93a5c332
commit 65e7891991
14 changed files with 101 additions and 61 deletions

View File

@ -14,6 +14,7 @@ import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*;
import mindustry.world.meta.*;
import static mindustry.Vars.*;
@ -68,7 +69,7 @@ public class EnergyFieldAbility extends Ability{
t.add(Core.bundle.format("bullet.damage", damage));
if(status != StatusEffects.none){
t.row();
t.add((status.hasEmoji() ? status.emoji() : "") + "[stat]" + status.localizedName);
t.add((status.hasEmoji() ? status.emoji() : "") + "[stat]" + status.localizedName).with(l -> StatValues.withTooltip(l, status));
}
if(displayHeal){
t.row();

View File

@ -115,7 +115,7 @@ public class StatusEffect extends UnlockableContent{
//don't list affinities *and* reactions, as that would be redundant
if(!reacts){
for(var e : affinities.toSeq().sort()){
stats.add(Stat.affinities, e.emoji() + "" + e);
stats.add(Stat.affinities, e.emoji() + e);
}
if(affinities.size > 0 && transitionDamage != 0){

View File

@ -1,35 +0,0 @@
package mindustry.ui;
import arc.graphics.g2d.*;
import arc.scene.ui.*;
import arc.scene.ui.layout.*;
import arc.util.*;
import mindustry.core.*;
import mindustry.type.*;
public class ItemImage extends Stack{
public ItemImage(TextureRegion region, int amount){
add(new Table(o -> {
o.left();
o.add(new Image(region)).size(32f).scaling(Scaling.fit);
}));
if(amount != 0){
add(new Table(t -> {
t.left().bottom();
t.add(amount >= 1000 ? UI.formatAmount(amount) : amount + "").style(Styles.outlineLabel);
t.pack();
}));
}
}
public ItemImage(ItemStack stack){
this(stack.item.uiIcon, stack.amount);
}
public ItemImage(PayloadStack stack){
this(stack.item.uiIcon, stack.amount);
}
}

View File

@ -25,6 +25,7 @@ import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.blocks.ConstructBlock.*;
import mindustry.world.meta.*;
import static mindustry.Vars.*;
@ -465,7 +466,7 @@ public class PlacementFragment{
for(int i = 0; i < counts.length; i++){
if(counts[i] > 0){
var type = content.unit(i);
unitlist.add(new ItemImage(type.uiIcon, counts[i])).tooltip(type.localizedName).pad(4).with(b -> {
unitlist.add(StatValues.stack(type, counts[i])).tooltip(type.localizedName).pad(4).with(b -> {
var listener = new ClickListener();
//left click -> select

View File

@ -89,7 +89,7 @@ public class Reconstructor extends UnitBlock{
table.table(Styles.grayPanel, t -> {
t.left();
t.image(upgrade[0].uiIcon).size(40).pad(10f).left().scaling(Scaling.fit);
t.image(upgrade[0].uiIcon).size(40).pad(10f).left().scaling(Scaling.fit).with(i -> StatValues.withTooltip(i, upgrade[0]));
t.table(info -> {
info.add(upgrade[0].localizedName).left();
info.row();
@ -104,7 +104,7 @@ public class Reconstructor extends UnitBlock{
table.table(Styles.grayPanel, t -> {
t.left();
t.image(upgrade[1].uiIcon).size(40).pad(10f).right().scaling(Scaling.fit);
t.image(upgrade[1].uiIcon).size(40).pad(10f).right().scaling(Scaling.fit).with(i -> StatValues.withTooltip(i, upgrade[1]));
t.table(info -> {
info.add(upgrade[1].localizedName).right();
info.row();

View File

@ -150,7 +150,7 @@ public class UnitAssembler extends PayloadBlock{
}
if(plan.unit.unlockedNow()){
t.image(plan.unit.uiIcon).scaling(Scaling.fit).size(40).pad(10f).left();
t.image(plan.unit.uiIcon).scaling(Scaling.fit).size(40).pad(10f).left().with(i -> StatValues.withTooltip(i, plan.unit));
t.table(info -> {
info.defaults().left();
info.add(plan.unit.localizedName);
@ -170,7 +170,7 @@ public class UnitAssembler extends PayloadBlock{
}
PayloadStack stack = plan.requirements.get(i);
req.add(new ItemImage(stack)).pad(5);
req.add(StatValues.stack(stack)).pad(5);
}
}).right().grow().pad(10f);
}else{

View File

@ -122,7 +122,7 @@ public class UnitFactory extends UnitBlock{
}
if(plan.unit.unlockedNow()){
t.image(plan.unit.uiIcon).size(40).pad(10f).left().scaling(Scaling.fit);
t.image(plan.unit.uiIcon).size(40).pad(10f).left().scaling(Scaling.fit).with(i -> StatValues.withTooltip(i, plan.unit));
t.table(info -> {
info.add(plan.unit.localizedName).left();
info.row();

View File

@ -6,6 +6,7 @@ import mindustry.gen.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.*;
import mindustry.world.meta.*;
public class ConsumeItemDynamic extends Consume{
public final Func<Building, ItemStack[]> items;
@ -42,7 +43,7 @@ public class ConsumeItemDynamic extends Consume{
int i = 0;
for(ItemStack stack : items.get(build)){
table.add(new ReqImage(new ItemImage(stack.item.uiIcon, Math.round(stack.amount * multiplier.get(build))),
table.add(new ReqImage(StatValues.stack(stack.item, Math.round(stack.amount * multiplier.get(build))),
() -> build.items != null && build.items.has(stack.item, Math.round(stack.amount * multiplier.get(build))))).padRight(8).left();
if(++i % 4 == 0) table.row();
}

View File

@ -31,7 +31,7 @@ public class ConsumeItemFilter extends Consume{
@Override
public void build(Building build, Table table){
MultiReqImage image = new MultiReqImage();
content.items().each(i -> filter.get(i) && i.unlockedNow(), item -> image.add(new ReqImage(new ItemImage(item.uiIcon, 1),
content.items().each(i -> filter.get(i) && i.unlockedNow(), item -> image.add(new ReqImage(StatValues.stack(item, 1),
() -> build.items.has(item))));
table.add(image).size(8 * 4);

View File

@ -33,7 +33,7 @@ public class ConsumeItems extends Consume{
table.table(c -> {
int i = 0;
for(var stack : items){
c.add(new ReqImage(new ItemImage(stack.item.uiIcon, Math.round(stack.amount * multiplier.get(build))),
c.add(new ReqImage(StatValues.stack(stack.item, Math.round(stack.amount * multiplier.get(build))),
() -> build.items.has(stack.item, Math.round(stack.amount * multiplier.get(build))))).padRight(8);
if(++i % 4 == 0) c.row();
}

View File

@ -63,7 +63,7 @@ public class ConsumePayloadDynamic extends Consume{
table.table(c -> {
int i = 0;
for(var stack : pay){
c.add(new ReqImage(new ItemImage(stack.item.uiIcon, Math.round(stack.amount * multiplier.get(build))),
c.add(new ReqImage(StatValues.stack(stack.item, Math.round(stack.amount * multiplier.get(build))),
() -> inv.contains(stack.item, Math.round(stack.amount * multiplier.get(build))))).padRight(8);
if(++i % 4 == 0) c.row();
}

View File

@ -57,7 +57,7 @@ public class ConsumePayloadFilter extends Consume{
MultiReqImage image = new MultiReqImage();
content.blocks().each(i -> filter.get(i) && i.unlockedNow(),
block -> image.add(new ReqImage(new ItemImage(block.uiIcon, 1),
block -> image.add(new ReqImage(StatValues.stack(block, 1),
() -> inv.contains(block, 1)))
);

View File

@ -38,7 +38,7 @@ public class ConsumePayloads extends Consume{
for(var stack : payloads){
stats.add(Stat.input, t -> {
t.add(new ItemImage(stack));
t.add(StatValues.stack(stack));
t.add(stack.item.localizedName).padLeft(4).padRight(4);
});
}
@ -51,7 +51,7 @@ public class ConsumePayloads extends Consume{
table.table(c -> {
int i = 0;
for(var stack : payloads){
c.add(new ReqImage(new ItemImage(stack.item.uiIcon, Math.round(stack.amount * multiplier.get(build))),
c.add(new ReqImage(StatValues.stack(stack.item, Math.round(stack.amount * multiplier.get(build))),
() -> inv.contains(stack.item, Math.round(stack.amount * multiplier.get(build))))).padRight(8);
if(++i % 4 == 0) c.row();
}

View File

@ -5,12 +5,16 @@ import arc.func.*;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.*;
import arc.scene.*;
import arc.scene.event.*;
import arc.scene.ui.*;
import arc.scene.ui.Tooltip.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.*;
import mindustry.*;
import mindustry.content.*;
import mindustry.core.*;
import mindustry.ctype.*;
import mindustry.entities.abilities.*;
import mindustry.entities.bullet.*;
@ -157,6 +161,73 @@ public class StatValues{
return t;
}
public static <T extends Element> T withTooltip(T element, UnlockableContent content, boolean tooltip){
if(content != null){
if(!mobile){
if(tooltip){
element.addListener(Tooltips.getInstance().create(content.localizedName, mobile));
}
element.addListener(new HandCursorListener(() -> !content.isHidden(), true));
}
element.clicked(() -> {
if(!content.isHidden()){
Vars.ui.content.show(content);
}
});
}
return element;
}
public static <T extends Element> T withTooltip(T element, UnlockableContent content){
return withTooltip(element, content, false);
}
/** Displays an item with a specified amount. */
private static Stack stack(TextureRegion region, int amount, @Nullable UnlockableContent content, boolean tooltip){
Stack stack = new Stack();
stack.add(new Table(o -> {
o.left();
o.add(new Image(region)).size(32f).scaling(Scaling.fit);
}));
if(amount != 0){
stack.add(new Table(t -> {
t.left().bottom();
t.add(amount >= 1000 ? UI.formatAmount(amount) : amount + "").style(Styles.outlineLabel);
t.pack();
}));
}
withTooltip(stack, content, tooltip);
return stack;
}
/** Displays an item with a specified amount. */
private static Stack stack(TextureRegion region, int amount, @Nullable UnlockableContent content){
return stack(region, amount, content, true);
}
public static Stack stack(ItemStack stack){
return stack(stack.item.uiIcon, stack.amount, stack.item);
}
public static Stack stack(UnlockableContent item, int amount){
return stack(item.uiIcon, amount, item);
}
public static Stack stack(UnlockableContent item, int amount, boolean tooltip){
return stack(item.uiIcon, amount, item, tooltip);
}
public static Stack stack(Item item){
return stack(item.uiIcon, 0, item);
}
public static Stack stack(PayloadStack stack){
return stack(stack.item.uiIcon, stack.amount, stack.item);
}
public static Table displayItem(Item item){
return displayItem(item, 0);
@ -164,7 +235,7 @@ public class StatValues{
public static Table displayItem(Item item, int amount, boolean showName){
Table t = new Table();
t.add(new ItemImage(new ItemStack(item, amount)));
t.add(stack(item, amount, !showName));
if(showName) t.add(item.localizedName).padLeft(4 + amount > 99 ? 4 : 0);
return t;
}
@ -176,7 +247,7 @@ public class StatValues{
/** Displays the item with a "/sec" qualifier based on the time period, in ticks. */
public static Table displayItem(Item item, int amount, float timePeriod, boolean showName){
Table t = new Table();
t.add(new ItemImage(item.uiIcon, amount));
t.add(stack(item, amount, !showName));
t.add((showName ? item.localizedName + "\n" : "") + "[lightgray]" + Strings.autoFixed(amount / (timePeriod / 60f), 2) + StatUnit.perSecond.localized()).padLeft(2).padRight(5).style(Styles.outlineLabel);
return t;
}
@ -184,7 +255,7 @@ public class StatValues{
/** Displays the item with a "/sec" qualifier based on the time period, in ticks. */
public static Table displayItemPercent(Item item, int percent, boolean showName){
Table t = new Table();
t.add(new ItemImage(item.uiIcon, 0));
t.add(stack(item, 0, !showName));
t.add((showName ? item.localizedName + "\n" : "") + "[lightgray]" + percent + "%").padLeft(2).padRight(5).style(Styles.outlineLabel);
return t;
}
@ -266,7 +337,7 @@ public class StatValues{
if(!check.get(item)) continue;
any = true;
if(item.uiIcon.found()) l.image(item.uiIcon).size(iconSmall).padRight(2).padLeft(2).padTop(3).padBottom(3);
if(item.uiIcon.found()) l.image(item.uiIcon).size(iconSmall).scaling(Scaling.fit).padRight(2).padLeft(2).padTop(3).padBottom(3).with(img -> withTooltip(img, item, false));
l.add(item.localizedName).left().padLeft(1).padRight(4).colspan(item.uiIcon.found() ? 1 : 2);
if(i % 5 == 4){
l.row();
@ -304,7 +375,7 @@ public class StatValues{
b.table(info -> {
info.left();
info.add(block.localizedName).left().row();
info.add(block.itemDrop.emoji()).left();
info.add(block.itemDrop.emoji()).with(l -> withTooltip(l, block.itemDrop)).left();
}).grow();
if(multipliers != null){
b.add(Strings.autoFixed(60f / (Math.max(drillTime + drillMultiplier * block.itemDrop.hardness, drillTime) / multipliers.get(block.itemDrop, 1f)) * size, 2) + StatUnit.perSecond.localized())
@ -325,7 +396,7 @@ public class StatValues{
if(!filter.get(liquid)) continue;
c.table(Styles.grayPanel, b -> {
b.image(liquid.uiIcon).size(40).pad(10f).left().scaling(Scaling.fit);
b.image(liquid.uiIcon).size(40).pad(10f).left().scaling(Scaling.fit).with(i -> withTooltip(i, liquid, false));;
b.table(info -> {
info.add(liquid.localizedName).left().row();
info.add(Strings.autoFixed(maxUsed * 60f, 2) + StatUnit.perSecond.localized()).left().color(Color.lightGray);
@ -354,7 +425,7 @@ public class StatValues{
if(!filter.get(liquid)) continue;
c.table(Styles.grayPanel, b -> {
b.image(liquid.uiIcon).size(40).pad(10f).left().scaling(Scaling.fit);
b.image(liquid.uiIcon).size(40).pad(10f).left().scaling(Scaling.fit).with(i -> withTooltip(i, liquid, false));;
b.table(info -> {
info.add(liquid.localizedName).left().row();
info.add(Strings.autoFixed(amount * 60f, 2) + StatUnit.perSecond.localized()).left().color(Color.lightGray);
@ -479,7 +550,7 @@ public class StatValues{
//no point in displaying unit icon twice
if(!compact && !(t instanceof Turret)){
bt.table(title -> {
title.image(icon(t)).size(3 * 8).padRight(4).right().scaling(Scaling.fit).top();
title.image(icon(t)).size(3 * 8).padRight(4).right().scaling(Scaling.fit).top().with(i -> withTooltip(i, t, false));
title.add(t.localizedName).padRight(10).left().top();
});
bt.row();
@ -556,7 +627,8 @@ public class StatValues{
}
if(type.status != StatusEffects.none){
sep(bt, (type.status.hasEmoji() ? type.status.emoji() : "") + "[stat]" + type.status.localizedName + (type.status.reactive ? "" : "[lightgray] ~ [stat]" + ((int)(type.statusDuration / 60f)) + "[lightgray] " + Core.bundle.get("unit.seconds")));
sep(bt, (type.status.hasEmoji() ? type.status.emoji() : "") + "[stat]" + type.status.localizedName + (type.status.reactive ? "" : "[lightgray] ~ [stat]" +
((int)(type.statusDuration / 60f)) + "[lightgray] " + Core.bundle.get("unit.seconds"))).with(c -> withTooltip(c, type.status));
}
if(type.intervalBullet != null){
@ -601,9 +673,9 @@ public class StatValues{
}
//for AmmoListValue
private static void sep(Table table, String text){
private static Cell<?> sep(Table table, String text){
table.row();
table.add(text);
return table.add(text);
}
//for AmmoListValue