diff --git a/src/main/java/brachy/modularui/api/value/IValue.java b/src/main/java/brachy/modularui/api/value/IValue.java index 4ab4d91f..77e33ea5 100644 --- a/src/main/java/brachy/modularui/api/value/IValue.java +++ b/src/main/java/brachy/modularui/api/value/IValue.java @@ -25,6 +25,11 @@ public interface IValue extends ISyncOrValue { */ void setValue(@UnknownNullability T value); + default T getOrDefault(T defaultValue) { + T t = getValue(); + return t != null ? t : defaultValue; + } + Class getValueType(); @Override diff --git a/src/main/java/brachy/modularui/drawable/GuiDraw.java b/src/main/java/brachy/modularui/drawable/GuiDraw.java index 32d96a2c..a7578760 100644 --- a/src/main/java/brachy/modularui/drawable/GuiDraw.java +++ b/src/main/java/brachy/modularui/drawable/GuiDraw.java @@ -1,6 +1,5 @@ package brachy.modularui.drawable; -import brachy.modularui.utils.MUIRenderTypes; import brachy.modularui.api.drawable.IRichTextBuilder; import brachy.modularui.drawable.text.TextRenderer; import brachy.modularui.screen.event.RichTooltipEvent; @@ -8,8 +7,9 @@ import brachy.modularui.screen.viewport.ModularGuiContext; import brachy.modularui.utils.Alignment; import brachy.modularui.utils.Color; -import brachy.modularui.utils.FormattingUtil; +import brachy.modularui.utils.MUIRenderTypes; import brachy.modularui.utils.RectangleF; +import brachy.modularui.utils.math.NumberFormat; import brachy.modularui.widget.sizer.Area; import net.minecraft.client.Minecraft; @@ -665,7 +665,7 @@ public static void drawStandardSlotAmountText(GuiContext context, int amount, St public static void drawAmountText(ModularGuiContext context, int amount, String format, int x, int y, int width, int height, Alignment alignment, float z) { if (amount <= 1) return; - String amountText = FormattingUtil.formatNumberReadable(amount, false); + String amountText = NumberFormat.AMOUNT_TEXT.format(amount); if (format != null) { amountText = format + amountText; } diff --git a/src/main/java/brachy/modularui/integration/emi/recipe/ModularUIEmiRecipe.java b/src/main/java/brachy/modularui/integration/emi/recipe/ModularUIEmiRecipe.java index a4f1d43e..ab7dd055 100644 --- a/src/main/java/brachy/modularui/integration/emi/recipe/ModularUIEmiRecipe.java +++ b/src/main/java/brachy/modularui/integration/emi/recipe/ModularUIEmiRecipe.java @@ -178,6 +178,7 @@ public List getTooltip(int mouseX, int mouseY) { IWidget hovered = screen.getContext().getTopHovered(); if (hovered instanceof ITooltip tooltip && tooltip.getTooltip() != null) { RichTooltip richTooltip = tooltip.getTooltip(); + if (richTooltip.autoUpdate()) richTooltip.markDirty(); richTooltip.isEmpty(); // causes the tooltip to rebuild if necessary IRichTextBuilder richTextBuilder = richTooltip.getRichText(); if (richTextBuilder instanceof RichText richText) { diff --git a/src/main/java/brachy/modularui/utils/FormattingUtil.java b/src/main/java/brachy/modularui/utils/FormattingUtil.java index 8fad9623..ea74277a 100755 --- a/src/main/java/brachy/modularui/utils/FormattingUtil.java +++ b/src/main/java/brachy/modularui/utils/FormattingUtil.java @@ -9,7 +9,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.math.BigInteger; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.Arrays; @@ -342,62 +341,6 @@ public static String formatNumbers(Object number) { return NUMBER_FORMAT.format(number); } - public static String formatNumberReadable(long number) { - return formatNumberReadable(number, false); - } - - public static String formatNumberReadable(long number, boolean milli) { - return formatNumberReadable(number, milli, DECIMAL_FORMAT_1F, null); - } - - public static String formatNumberReadable2F(double number, boolean milli) { - return formatNumberReadable(number, milli, DECIMAL_FORMAT_2F, null); - } - - /** - * Format number in engineering notation with SI prefixes [m, k, M, G, T, P, E, Z] - * - * @param number Number to format - * @param milli Whether the passed number is already in millis (e.g., mB) - * @param fmt Formatter to use for compacted number - * @param unit Optional unit to append - * @return Compacted number with SI prefix - */ - public static String formatNumberReadable(double number, boolean milli, NumberFormat fmt, @Nullable String unit) { - StringBuilder sb = new StringBuilder(); - if (number < 0) { - number = -number; - sb.append('-'); - } - - if (milli && number >= 1e3) { - milli = false; - number /= 1e3; - } - - int exp = 0; - if (number >= 1e3) { - exp = (int) Math.log10(number) / 3; - if (exp > 7) exp = 7; - if (exp > 0) number /= Math.pow(1e3, exp); - } - - sb.append(fmt.format(number)); - if (exp > 0) sb.append("kMGTPEZ".charAt(exp - 1)); - else if (milli && number != 0) sb.append('m'); - - if (unit != null) sb.append(unit); - return sb.toString(); - } - - public static String formatNumberOrSic(BigInteger number, BigInteger threshold) { - return number.compareTo(threshold) > 0 ? DECIMAL_FORMAT_SIC_2F.format(number) : formatNumbers(number); - } - - public static String formatBuckets(long mB) { - return formatNumberReadable(mB, true, DECIMAL_FORMAT_2F, "B"); - } - @NotNull public static String formatNumber2Places(float number) { return DECIMAL_FORMAT_2F.format(number); diff --git a/src/main/java/brachy/modularui/utils/math/NumberFormat.java b/src/main/java/brachy/modularui/utils/math/NumberFormat.java index 41ddc874..3b46cfe3 100644 --- a/src/main/java/brachy/modularui/utils/math/NumberFormat.java +++ b/src/main/java/brachy/modularui/utils/math/NumberFormat.java @@ -31,6 +31,7 @@ public class NumberFormat { public static final Params AMOUNT_TEXT = DEFAULT.copyToBuilder() .roundingMode(RoundingMode.DOWN) + .maxLength(3) .build(); public static Params params(DecimalFormat format, int maxLength, boolean considerOnlyDecimalsForLength, @@ -56,8 +57,8 @@ public Params(DecimalFormat format, int maxLength, boolean considerOnlyDecimalsF this.considerMinusForLength = considerMinusForLength; this.considerSuffixForLength = considerSuffixForLength; this.spaceAfterNumber = spaceAfterNumber; - if (!this.considerOnlyDecimalsForLength && this.maxLength < 4) { - throw new IllegalArgumentException("Max length must be at least 4 characters"); + if (!this.considerOnlyDecimalsForLength && this.maxLength < 1) { + throw new IllegalArgumentException("Max length must be at least 1 character"); } } diff --git a/src/main/java/brachy/modularui/utils/math/SIPrefix.java b/src/main/java/brachy/modularui/utils/math/SIPrefix.java index 84c0418a..744225f7 100644 --- a/src/main/java/brachy/modularui/utils/math/SIPrefix.java +++ b/src/main/java/brachy/modularui/utils/math/SIPrefix.java @@ -11,7 +11,7 @@ public enum SIPrefix { Ronna('R', 27), Yotta('Y', 24), Zetta('Z', 21), - Exa('X', 18), // this should actually be E, but this clashes with euler's number e = 2.71... + Exa('X', 18), // this should actually be E, but this clashes with Euler's number e = 2.71... Peta('P', 15), Tera('T', 12), Giga('G', 9), diff --git a/src/main/java/brachy/modularui/widget/WidgetTree.java b/src/main/java/brachy/modularui/widget/WidgetTree.java index ebc06b9a..75a138d8 100644 --- a/src/main/java/brachy/modularui/widget/WidgetTree.java +++ b/src/main/java/brachy/modularui/widget/WidgetTree.java @@ -6,8 +6,8 @@ import brachy.modularui.api.widget.IWidget; import brachy.modularui.screen.ModularPanel; import brachy.modularui.screen.viewport.ModularGuiContext; -import brachy.modularui.utils.FormattingUtil; import brachy.modularui.utils.TreeUtil; +import brachy.modularui.utils.math.NumberFormat; import brachy.modularui.value.sync.ModularSyncManager; import brachy.modularui.value.sync.PanelSyncManager; import brachy.modularui.widget.sizer.ResizeNode; @@ -302,8 +302,8 @@ public static void resizeInternal(ResizeNode parent, boolean onOpen) { if (WidgetTree.logResizeTime) { time = Util.getNanos() - time; ModularUI.LOGGER.info("Resized widget tree in {} ns and {} ns for full resize.", - FormattingUtil.formatNumbers(time), - FormattingUtil.formatNumbers(time)); + NumberFormat.formatNanos(time), + NumberFormat.formatNanos(time)); } } diff --git a/src/main/java/brachy/modularui/widgets/AbstractFluidDisplayWidget.java b/src/main/java/brachy/modularui/widgets/AbstractFluidDisplayWidget.java index 1798c492..14cbcbb1 100644 --- a/src/main/java/brachy/modularui/widgets/AbstractFluidDisplayWidget.java +++ b/src/main/java/brachy/modularui/widgets/AbstractFluidDisplayWidget.java @@ -9,8 +9,8 @@ import brachy.modularui.screen.viewport.ModularGuiContext; import brachy.modularui.theme.WidgetThemeEntry; import brachy.modularui.utils.Alignment; -import brachy.modularui.utils.FormattingUtil; import brachy.modularui.utils.math.MathUtils; +import brachy.modularui.utils.math.NumberFormat; import brachy.modularui.utils.math.SIPrefix; import brachy.modularui.widget.Widget; import brachy.modularui.widget.sizer.Box; @@ -19,7 +19,6 @@ import lombok.Getter; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; public abstract class AbstractFluidDisplayWidget> extends Widget implements IngredientProvider { @@ -63,12 +62,10 @@ public void draw(ModularGuiContext context, WidgetThemeEntry widgetTheme) { public void drawOverlay(ModularGuiContext context, WidgetThemeEntry widgetTheme) { super.drawOverlay(context, widgetTheme); FluidStack fluid = getFluidStack(); - if (fluid != null && displayAmountText()) { - String s = FormattingUtil.formatNumberReadable2F(getBaseUnitAmount(fluid.getAmount()), false) + - getBaseUnit(); + if (!fluid.isEmpty() && displayAmountText()) { + String s = NumberFormat.format(getBaseUnitAmount(fluid.getAmount()), NumberFormat.AMOUNT_TEXT) + getBaseUnit(); // mc doesn't consider the 1px border in item slots for amount text, but it looks weird when it touches the - // left border, so - // we only apply padding there + // left border, so we only apply padding there GuiDraw.drawScaledAlignedTextInBox(context, s, this.contentPadding.left(), 0, getArea().width - this.contentPadding.left(), getArea().height, Alignment.BottomRight); } @@ -76,7 +73,6 @@ public void drawOverlay(ModularGuiContext context, WidgetThemeEntry widgetThe protected abstract boolean displayAmountText(); - @Nullable protected abstract FluidStack getFluidStack(); /** diff --git a/src/main/java/brachy/modularui/widgets/FluidDisplayWidget.java b/src/main/java/brachy/modularui/widgets/FluidDisplayWidget.java index 1271072a..4006ed51 100644 --- a/src/main/java/brachy/modularui/widgets/FluidDisplayWidget.java +++ b/src/main/java/brachy/modularui/widgets/FluidDisplayWidget.java @@ -37,7 +37,7 @@ protected boolean displayAmountText() { @Override protected @Nullable FluidStack getFluidStack() { - return this.value != null ? this.value.getValue() : null; + return this.value != null ? this.value.getOrDefault(FluidStack.EMPTY) : FluidStack.EMPTY; } public FluidDisplayWidget value(IValue value) { diff --git a/src/main/java/brachy/modularui/widgets/slot/FluidSlot.java b/src/main/java/brachy/modularui/widgets/slot/FluidSlot.java index 50791d00..17ca116b 100644 --- a/src/main/java/brachy/modularui/widgets/slot/FluidSlot.java +++ b/src/main/java/brachy/modularui/widgets/slot/FluidSlot.java @@ -149,6 +149,7 @@ protected boolean displayAmountText() { @Override public void drawOverlay(ModularGuiContext context, WidgetThemeEntry widgetTheme) { + super.drawOverlay(context, widgetTheme); if (isHovering()) { RenderSystem.colorMask(true, true, true, false); GuiDraw.drawRect(context.getGraphics(), 1, 1, getArea().w() - 2, getArea().h() - 2, getSlotHoverColor()); @@ -212,9 +213,8 @@ public int getCapacity() { return this.alwaysShowFull ? 0 : getFluidTank().getCapacity(); } - @Nullable public FluidStack getFluidStack() { - return this.syncHandler == null ? null : this.syncHandler.getValue(); + return this.syncHandler == null ? FluidStack.EMPTY : this.syncHandler.getOrDefault(FluidStack.EMPTY); } public IFluidTank getFluidTank() {