diff --git a/src/main/java/com/cleanroommc/modularui/test/TestTile.java b/src/main/java/com/cleanroommc/modularui/test/TestTile.java index 904be414..a6f3420c 100644 --- a/src/main/java/com/cleanroommc/modularui/test/TestTile.java +++ b/src/main/java/com/cleanroommc/modularui/test/TestTile.java @@ -35,7 +35,7 @@ public class TestTile extends TileEntity implements IGuiHolder, ITickable { private final FluidTank fluidTank = new FluidTank(10000); - private final FluidTank fluidTankPhantom = new FluidTank(10000); + private final FluidTank fluidTankPhantom = new FluidTank(Integer.MAX_VALUE); private long time = 0; private int val, val2 = 0; private String value = ""; diff --git a/src/main/java/com/cleanroommc/modularui/utils/NumberFormat.java b/src/main/java/com/cleanroommc/modularui/utils/NumberFormat.java index 0e3ee95f..932d3697 100644 --- a/src/main/java/com/cleanroommc/modularui/utils/NumberFormat.java +++ b/src/main/java/com/cleanroommc/modularui/utils/NumberFormat.java @@ -1,75 +1,60 @@ package com.cleanroommc.modularui.utils; -import org.jetbrains.annotations.NotNull; +import org.apache.commons.lang3.StringUtils; import java.text.DecimalFormat; -import java.util.Map; -import java.util.NavigableMap; -import java.util.TreeMap; public class NumberFormat { - private static final NavigableMap suffixesByPower = new TreeMap<>(); - private static final java.text.NumberFormat[] NUMBER_FORMAT = { - new DecimalFormat("0."), - new DecimalFormat("0.#"), - new DecimalFormat("0.##"), - new DecimalFormat("0.###"), - new DecimalFormat("0.####"), - new DecimalFormat("0.#####"), - new DecimalFormat("0.######"), - new DecimalFormat("0.#######"), - new DecimalFormat("0.########"), - new DecimalFormat("0.#########"), - }; + public static final DecimalFormat FORMAT = new DecimalFormat("0.###"); - static { - suffixesByPower.put(0.000_000_000_000_000_001D, "a"); - suffixesByPower.put(0.000_000_000_000_001D, "f"); - suffixesByPower.put(0.000_000_000_001D, "p"); - suffixesByPower.put(0.000_000_001D, "n"); - suffixesByPower.put(0.000_001D, "u"); - suffixesByPower.put(0.001D, "m"); - suffixesByPower.put(1_000D, "k"); - suffixesByPower.put(1_000_000D, "M"); - suffixesByPower.put(1_000_000_000D, "G"); - suffixesByPower.put(1_000_000000_000D, "T"); - suffixesByPower.put(1_000_000000_000_000D, "P"); - suffixesByPower.put(1_000_000000_000_000_000D, "E"); + private static final double[] FACTORS_HIGH = {1e3, 1e6, 1e9, 1e12, 1e15, 1e18}; + private static final double[] FACTORS_LOW = {1e-3, 1e-6, 1e-9, 1e-12, 1e-15, 1e-18}; + private static final String[] SUFFIX_HIGH = {"k", "M", "G", "T", "P", "E"}; + private static final String[] SUFFIX_LOW = {"m", "u", "n", "p", "f", "a"}; + + public static String formatWithMaxDigits(double value) { + return format(value, 4, true); } - @NotNull - public static String format(double value, int precision) { - //Double.MIN_VALUE == -Double.MIN_VALUE so we need an adjustment here - if (value == Double.MIN_VALUE) return format(Double.MIN_VALUE + 1, precision); - if (value == 0) return "0"; - if (value < 0) return '-' + format(-value, precision); - double divideBy; - String suffix; - if (value < pow(10, precision)) { - divideBy = 1; - suffix = ""; - } else { - Map.Entry e = suffixesByPower.floorEntry(value); - divideBy = e.getKey(); - suffix = e.getValue(); - } + public static String formatWithMaxDigits(double value, int maxDigits) { + return format(value, maxDigits, true); + } - double truncated = value / (divideBy / 10); //the number part of the output times 10 - boolean hasDecimal = truncated < 100 && (truncated / 10D) != (truncated / 10); - return hasDecimal ? NUMBER_FORMAT[precision].format(truncated / 10D) + suffix : NUMBER_FORMAT[precision].format(truncated / 10) + suffix; + public static String formatWithMaxDecimals(double value, int decimals) { + return format(value, decimals, false); } - @NotNull - public static String format(double value) { - return format(value, 3); + private static String format(double value, int precision, boolean maxDigits) { + if (value >= 1000) { + int index; + for (index = 0; index < 5; index++) { + if (value < FACTORS_HIGH[index + 1]) { + break; + } + } + return formatToString(value / FACTORS_HIGH[index], precision, maxDigits, SUFFIX_HIGH[index]); + } + if (value < 1) { + int index; + for (index = 0; index < 5; index++) { + if (value >= FACTORS_LOW[index]) { + break; + } + } + return formatToString(value / FACTORS_LOW[index], precision, maxDigits, SUFFIX_LOW[index]); + } + return formatToString(value, precision, maxDigits, StringUtils.EMPTY); } - private static int pow(int num, int e) { - int result = num; - for (int i = 0; i < e; i++) { - result *= num; + private static String formatToString(double value, int precision, boolean maxDigits, String suffix) { + if (maxDigits) { + String[] parts = String.valueOf(value).split("\\."); + if (parts.length > 1) { + precision -= parts[0].length(); + } } - return result; + FORMAT.setMaximumFractionDigits(precision); + return FORMAT.format(value) + suffix; } } diff --git a/src/main/java/com/cleanroommc/modularui/widgets/FluidSlot.java b/src/main/java/com/cleanroommc/modularui/widgets/FluidSlot.java index 300492f9..4e73adf8 100644 --- a/src/main/java/com/cleanroommc/modularui/widgets/FluidSlot.java +++ b/src/main/java/com/cleanroommc/modularui/widgets/FluidSlot.java @@ -33,6 +33,9 @@ public class FluidSlot extends Widget implements Interactable, JeiGhostIngredientSlot, JeiIngredientProvider { + private static final String UNIT_BUCKET = "B"; + private static final String UNIT_LITER = "L"; + private static final IFluidTank EMPTY = new FluidTank(0); private final TextRenderer textRenderer = new TextRenderer(); @@ -46,16 +49,15 @@ public FluidSlot() { flex().startDefaultMode() .size(18, 18) .endDefaultMode(); - + tooltip().setAutoUpdate(true).setHasTitleMargin(true); tooltipBuilder(tooltip -> { - tooltip.setHasTitleMargin(true); IFluidTank fluidTank = getFluidTank(); FluidStack fluid = this.syncHandler.getValue(); if (this.syncHandler.isPhantom()) { if (fluid != null) { tooltip.addLine(IKey.str(fluid.getLocalizedName())); if (this.syncHandler.controlsAmount()) { - tooltip.addLine(IKey.format("modularui.fluid.phantom.amount", fluid.amount)); + tooltip.addLine(IKey.format("modularui.fluid.phantom.amount", formatFluidAmount(fluid.amount), getBaseUnit())); } } else { tooltip.addLine(IKey.format("modularui.fluid.empty")); @@ -66,7 +68,7 @@ public FluidSlot() { } else { if (fluid != null) { tooltip.addLine(IKey.str(fluid.getLocalizedName())); - tooltip.addLine(IKey.format("modularui.fluid.amount", fluid.amount, fluidTank.getCapacity())); + tooltip.addLine(IKey.format("modularui.fluid.amount", formatFluidAmount(fluid.amount), formatFluidAmount(fluidTank.getCapacity()), getBaseUnit())); addAdditionalFluidInfo(tooltip, fluid); } else { tooltip.addLine(IKey.format("modularui.fluid.empty")); @@ -92,6 +94,19 @@ public FluidSlot() { public void addAdditionalFluidInfo(Tooltip tooltip, FluidStack fluidStack) { } + public String formatFluidAmount(double amount) { + NumberFormat.FORMAT.setMaximumFractionDigits(3); + return NumberFormat.FORMAT.format(getBaseUnitAmount(amount)); + } + + protected double getBaseUnitAmount(double amount) { + return amount / 1000; + } + + protected String getBaseUnit() { + return UNIT_BUCKET; + } + @Override public void onInit() { this.textRenderer.setShadow(true); @@ -127,7 +142,7 @@ public void draw(GuiContext context, WidgetTheme widgetTheme) { this.overlayTexture.draw(context, getArea()); } if (content != null && this.syncHandler.controlsAmount()) { - String s = NumberFormat.format(content.amount); + String s = NumberFormat.formatWithMaxDigits(getBaseUnitAmount(content.amount)) + getBaseUnit(); this.textRenderer.setAlignment(Alignment.CenterRight, getArea().width - this.contentOffsetX - 1f); this.textRenderer.setPos((int) (this.contentOffsetX + 0.5f), (int) (getArea().height - 5.5f)); this.textRenderer.draw(s); diff --git a/src/main/java/com/cleanroommc/modularui/widgets/ItemSlot.java b/src/main/java/com/cleanroommc/modularui/widgets/ItemSlot.java index 5b1f1779..35458d8d 100644 --- a/src/main/java/com/cleanroommc/modularui/widgets/ItemSlot.java +++ b/src/main/java/com/cleanroommc/modularui/widgets/ItemSlot.java @@ -41,8 +41,8 @@ public class ItemSlot extends Widget implements IVanillaSlot, Interact private ItemSlotSH syncHandler; public ItemSlot() { + tooltip().setAutoUpdate(true).setHasTitleMargin(true); tooltipBuilder(tooltip -> { - tooltip.setAutoUpdate(true).setHasTitleMargin(true); tooltip.excludeArea(getArea()); if (!isSynced()) return; ItemStack stack = getSlot().getStack(); @@ -218,7 +218,7 @@ private void drawSlot(Slot slotIn) { } // render the amount overlay if (amount > 1 || format != null) { - String amountText = NumberFormat.format(amount, 2); + String amountText = NumberFormat.formatWithMaxDigits(amount); if (format != null) { amountText = format + amountText; } diff --git a/src/main/resources/assets/modularui/lang/en_us.lang b/src/main/resources/assets/modularui/lang/en_us.lang index 6a7fcaec..ca7553ac 100644 --- a/src/main/resources/assets/modularui/lang/en_us.lang +++ b/src/main/resources/assets/modularui/lang/en_us.lang @@ -4,8 +4,8 @@ modularui.increment.tooltip=§7Click to increase the number by §6%d§7\nHold sh modularui.decrement.tooltip=§7Click to decrease the number by §6%d§7\nHold shift[§6%d§7], ctrl[§6%d§7] or shift+ctrl[§6%d§7] modularui.amount=§9Amount: %,d modularui.fluid.empty=Empty -modularui.fluid.amount=§9Amount: %,d/%,d L -modularui.fluid.phantom.amount=§9Amount: %,d L +modularui.fluid.amount=§9Amount: %s/%s %s +modularui.fluid.phantom.amount=§9Amount: %s %s modularui.fluid.phantom.control=§7Scroll wheel up increases amount, down decreases.\n§7Shift[§6x10§7],Ctrl[§ex100§7],Alt[§ax1000§7]\n§7Right click increases amount, left click decreases.\n§7Shift + left click to clear. modularui.item.phantom.control=§7Scroll wheel up increases amount, down decreases.\n§7Shift[§6x4§7],Ctrl[§ex16§7],Alt[§ax64§7]\n§7Right click increases amount, left click decreases.\n§7Shift + left click to clear.