aboutsummaryrefslogtreecommitdiff
path: root/runtime-frontend/widgets/src/main/java/me
diff options
context:
space:
mode:
Diffstat (limited to 'runtime-frontend/widgets/src/main/java/me')
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/tooltip/MissingStacksTooltip.java106
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/tooltip/MissingStacksTooltipProviderImpl.java37
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/ArrowWidget.java98
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/BatchedSlotsImpl.java350
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/BurningFireWidget.java98
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/ButtonWidget.java336
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/DelegateWidgetWithTranslate.java133
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/DrawableWidget.java50
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/EntryWidget.java605
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/FillRectangleDrawableConsumer.java65
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/ForwardingList.java156
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/LabelWidget.java311
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/MergedWidget.java119
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/NoOpWidget.java53
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/OverflowWidget.java160
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/PaddedCenterWidget.java58
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/PaddedWidget.java51
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/PanelWidget.java160
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/RendererWrappedWidget.java72
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/TextFieldWidget.java649
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/TexturedDrawableConsumer.java75
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/VanillaWrappedWidget.java82
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/WidgetsProviderImpl.java167
-rw-r--r--runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/package-info.java27
24 files changed, 4018 insertions, 0 deletions
diff --git a/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/tooltip/MissingStacksTooltip.java b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/tooltip/MissingStacksTooltip.java
new file mode 100644
index 000000000..696384d03
--- /dev/null
+++ b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/tooltip/MissingStacksTooltip.java
@@ -0,0 +1,106 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.impl.client.gui.tooltip;
+
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.blaze3d.vertex.Tesselator;
+import com.mojang.math.Matrix4f;
+import me.shedaniel.math.Rectangle;
+import me.shedaniel.rei.api.client.gui.SimpleDisplayRenderer;
+import me.shedaniel.rei.api.common.entry.EntryIngredient;
+import me.shedaniel.rei.api.common.entry.EntryStack;
+import net.minecraft.ChatFormatting;
+import net.minecraft.client.gui.Font;
+import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
+import net.minecraft.client.renderer.MultiBufferSource;
+import net.minecraft.client.renderer.entity.ItemRenderer;
+import net.minecraft.network.chat.Component;
+import net.minecraft.network.chat.TextComponent;
+import net.minecraft.network.chat.TranslatableComponent;
+import net.minecraft.util.Mth;
+import net.minecraft.world.inventory.tooltip.TooltipComponent;
+
+import java.util.List;
+
+public class MissingStacksTooltip implements ClientTooltipComponent, TooltipComponent {
+ private static final int MAX_WIDTH = 200;
+ private final List<EntryIngredient> stacks;
+
+ public MissingStacksTooltip(List<EntryIngredient> stacks) {
+ this.stacks = SimpleDisplayRenderer.simplify(stacks);
+ }
+
+ @Override
+ public int getHeight() {
+ int entrySize = 18;
+ int w = Math.max(1, MAX_WIDTH / entrySize);
+ int height = Math.min(6, Mth.ceil(stacks.size() / (float) w)) * entrySize + 2;
+ height += 12;
+ return height;
+ }
+
+ @Override
+ public int getWidth(Font font) {
+ int entrySize = 18;
+ int w = Math.max(1, MAX_WIDTH / entrySize);
+ int size = stacks.size();
+ int width = Math.min(size, w) * entrySize;
+ width = Math.max(width, font.width(new TranslatableComponent("text.rei.missing")));
+ return width;
+ }
+
+ @Override
+ public void renderImage(Font font, int x, int y, PoseStack poses, ItemRenderer renderer, int z) {
+ int entrySize = 18;
+ int w = Math.max(1, MAX_WIDTH / entrySize);
+ int i = 0;
+ poses.pushPose();
+ poses.translate(0, 0, z + 50);
+ for (EntryIngredient entry : stacks) {
+ int x1 = x + (i % w) * entrySize;
+ int y1 = y + 13 + (i / w) * entrySize;
+ i++;
+ if (i / w > 5) {
+ MultiBufferSource.BufferSource source = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder());
+ Component text = new TextComponent("+" + (stacks.size() - w * 6 + 1)).withStyle(ChatFormatting.GRAY);
+ font.drawInBatch(text, x1 + entrySize / 2 - font.width(text) / 2, y1 + entrySize / 2 - 1, -1, true, poses.last().pose(), source, false, 0, 15728880);
+ source.endBatch();
+ break;
+ } else {
+ EntryStack<?> stack;
+ if (entry.isEmpty()) stack = EntryStack.empty();
+ else if (entry.size() == 1) stack = entry.get(0);
+ else stack = entry.get(Mth.floor((System.currentTimeMillis() / 1000 % (double) entry.size())));
+ stack.render(poses, new Rectangle(x1, y1, entrySize, entrySize), -1000, -1000, 0);
+ }
+ }
+ poses.popPose();
+ }
+
+ @Override
+ public void renderText(Font font, int x, int y, Matrix4f pose, MultiBufferSource.BufferSource buffers) {
+ font.drawInBatch(new TranslatableComponent("text.rei.missing").withStyle(ChatFormatting.GRAY),
+ x, y + 2, -1, true, pose, buffers, false, 0, 15728880);
+ }
+}
diff --git a/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/tooltip/MissingStacksTooltipProviderImpl.java b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/tooltip/MissingStacksTooltipProviderImpl.java
new file mode 100644
index 000000000..66e027634
--- /dev/null
+++ b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/tooltip/MissingStacksTooltipProviderImpl.java
@@ -0,0 +1,37 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.impl.client.gui.tooltip;
+
+import me.shedaniel.rei.api.common.entry.EntryIngredient;
+import me.shedaniel.rei.impl.client.provider.MissingStacksTooltipProvider;
+import net.minecraft.world.inventory.tooltip.TooltipComponent;
+
+import java.util.List;
+
+public class MissingStacksTooltipProviderImpl implements MissingStacksTooltipProvider {
+ @Override
+ public TooltipComponent provide(List<EntryIngredient> stacks) {
+ return new MissingStacksTooltip(stacks);
+ }
+}
diff --git a/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/ArrowWidget.java b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/ArrowWidget.java
new file mode 100644
index 000000000..8afb30220
--- /dev/null
+++ b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/ArrowWidget.java
@@ -0,0 +1,98 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.impl.client.gui.widget.basewidgets;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.blaze3d.vertex.PoseStack;
+import me.shedaniel.clothconfig2.api.animator.NumberAnimator;
+import me.shedaniel.clothconfig2.api.animator.ValueAnimator;
+import me.shedaniel.math.Rectangle;
+import me.shedaniel.rei.api.client.REIRuntime;
+import me.shedaniel.rei.api.client.config.ConfigObject;
+import me.shedaniel.rei.api.client.gui.widgets.Arrow;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+import net.minecraft.util.Mth;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+final class ArrowWidget extends Arrow {
+ private Rectangle bounds;
+ private double animationDuration = -1;
+ private final NumberAnimator<Float> darkBackgroundAlpha = ValueAnimator.ofFloat()
+ .withConvention(() -> ConfigObject.getInstance().isUsingDarkTheme() ? 1.0F : 0.0F, ValueAnimator.typicalTransitionTime())
+ .asFloat();
+
+ public ArrowWidget(Rectangle bounds) {
+ this.bounds = new Rectangle(Objects.requireNonNull(bounds));
+ }
+
+ @Override
+ public double getAnimationDuration() {
+ return animationDuration;
+ }
+
+ @Override
+ public void setAnimationDuration(double animationDurationMS) {
+ this.animationDuration = animationDurationMS;
+ if (this.animationDuration <= 0)
+ this.animationDuration = -1;
+ }
+
+ @Override
+ public Rectangle getBounds() {
+ return bounds;
+ }
+
+ @Override
+ public void render(PoseStack matrices, int mouseX, int mouseY, float delta) {
+ this.darkBackgroundAlpha.update(delta);
+ renderBackground(matrices, false, 1.0F);
+ if (darkBackgroundAlpha.value() > 0.0F) {
+ renderBackground(matrices, true, this.darkBackgroundAlpha.value());
+ }
+ }
+
+ public void renderBackground(PoseStack matrices, boolean dark, float alpha) {
+ RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, alpha);
+ RenderSystem.setShaderTexture(0, REIRuntime.getInstance().getDefaultDisplayTexture(dark));
+ RenderSystem.enableBlend();
+ RenderSystem.blendFuncSeparate(770, 771, 1, 0);
+ RenderSystem.blendFunc(770, 771);
+ if (getAnimationDuration() > 0) {
+ int width = Mth.ceil((System.currentTimeMillis() / (animationDuration / 24) % 24d));
+ blit(matrices, getX() + width, getY(), 106 + width, 91, 24 - width, 17);
+ blit(matrices, getX(), getY(), 82, 91, width, 17);
+ } else {
+ blit(matrices, getX(), getY(), 106, 91, 24, 17);
+ }
+ RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
+ }
+
+ @Override
+ public List<? extends GuiEventListener> children() {
+ return Collections.emptyList();
+ }
+}
diff --git a/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/BatchedSlotsImpl.java b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/BatchedSlotsImpl.java
new file mode 100644
index 000000000..dc1b2e4dc
--- /dev/null
+++ b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/BatchedSlotsImpl.java
@@ -0,0 +1,350 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.impl.client.gui.widget.basewidgets;
+
+import com.google.common.collect.AbstractIterator;
+import com.google.common.collect.Iterables;
+import com.mojang.blaze3d.vertex.PoseStack;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import me.shedaniel.math.Point;
+import me.shedaniel.rei.api.client.config.ConfigObject;
+import me.shedaniel.rei.api.client.entry.renderer.BatchedEntryRenderer;
+import me.shedaniel.rei.api.client.entry.renderer.EntryRenderer;
+import me.shedaniel.rei.api.client.gui.widgets.BatchedSlots;
+import me.shedaniel.rei.api.client.gui.widgets.Slot;
+import me.shedaniel.rei.api.client.gui.widgets.Tooltip;
+import me.shedaniel.rei.api.client.gui.widgets.TooltipContext;
+import me.shedaniel.rei.api.common.entry.EntryStack;
+import me.shedaniel.rei.api.common.util.CollectionUtils;
+import me.shedaniel.rei.impl.client.util.CrashReportUtils;
+import net.minecraft.CrashReport;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+import net.minecraft.client.renderer.MultiBufferSource;
+import org.apache.commons.lang3.mutable.MutableInt;
+import org.apache.commons.lang3.mutable.MutableLong;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+final class BatchedSlotsImpl extends BatchedSlots implements ForwardingList<Slot> {
+ private final boolean fastEntryRendering = ConfigObject.getInstance().doesFastEntryRendering();
+ private final Int2ObjectMap<List<Object>> grouping = new Int2ObjectOpenHashMap<>();
+ private final List<Slot> toRender = new ArrayList<>();
+ private final List<Slot> delegateList = new DelegatedSlotList();
+ private int size;
+ public boolean debug;
+ public MutableInt debugSize = new MutableInt();
+ public MutableLong debugTime = new MutableLong();
+
+ @Override
+ public boolean isBatched() {
+ return fastEntryRendering;
+ }
+
+ @Override
+ public List<Slot> delegate() {
+ return delegateList;
+ }
+
+ @Override
+ public void addAllUnbatched(Collection<? extends Slot> slots) {
+ this.toRender.addAll(slots);
+ this.size += slots.size();
+ }
+
+ @Override
+ public void addDebugger(MutableInt size, MutableLong time) {
+ this.debug = true;
+ this.debugSize = size;
+ this.debugTime = time;
+ }
+
+ @Override
+ public void addUnbatched(Slot slot) {
+ this.toRender.add(slot);
+ this.size++;
+ }
+
+ @Override
+ public void render(PoseStack matrices, int mouseX, int mouseY, float delta) {
+ if (this.debug) {
+ render(false, null, null, matrices, mouseX, mouseY, delta);
+ } else {
+ render(true, debugSize, debugTime, matrices, mouseX, mouseY, delta);
+ }
+ }
+
+ public void render(boolean debugTime, MutableInt size, MutableLong time, PoseStack matrices, int mouseX, int mouseY, float delta) {
+ if (fastEntryRendering) {
+ for (List<Object> entries : grouping.values()) {
+ Object[] extraData = new Object[entries.size() / 2];
+ for (int i = 0; i < extraData.length; i++) {
+ extraData[i] = entries.get(i * 2 + 1);
+ }
+ renderBatched(debugTime, size, time, matrices, mouseX, mouseY, delta, groupingAsList(entries), extraData);
+ }
+ }
+ if (!toRender.isEmpty()) {
+ renderSlow(debugTime, size, time, matrices, mouseX, mouseY, delta, toRender);
+ }
+ }
+
+ public List<Slot> groupingsAsList() {
+ return CollectionUtils.concatUnmodifiable((Iterable<List<Slot>>) () -> new AbstractIterator<>() {
+ final Iterator<List<Object>> groups = grouping.values().iterator();
+
+ @Nullable
+ @Override
+ protected List<Slot> computeNext() {
+ if (groups.hasNext()) {
+ return groupingAsList(groups.next());
+ }
+ return endOfData();
+ }
+ });
+ }
+
+ public List<Slot> groupingAsList(List<Object> entries) {
+ return new AbstractList<>() {
+ @Override
+ public Slot get(int index) {
+ return (Slot) entries.get(index * 2);
+ }
+
+ @Override
+ public Iterator<Slot> iterator() {
+ return new AbstractIterator<>() {
+ public int i = 0;
+
+ @Override
+ protected Slot computeNext() {
+ if (i >= entries.size()) {
+ return endOfData();
+ }
+ Slot widget = (Slot) entries.get(i);
+ i += 2;
+ return widget;
+ }
+ };
+ }
+
+ @Override
+ public int size() {
+ return entries.size() / 2;
+ }
+ };
+ }
+
+ public static void renderEntries(boolean debugTime, MutableInt size, MutableLong time, boolean fastEntryRendering, PoseStack matrices, int mouseX, int mouseY, float delta, Collection<? extends Slot> entries) {
+ if (fastEntryRendering) {
+ Slot firstWidget = Iterables.getFirst(entries, null);
+ if (firstWidget == null) return;
+ EntryRenderer<?> renderer = firstWidget.getCurrentEntry().getRenderer();
+ if (renderer instanceof BatchedEntryRenderer) {
+ BatchedEntryRenderer<?, Object> firstRenderer = (BatchedEntryRenderer<?, Object>) renderer;
+ Object[] extraData = new Object[entries.size()];
+ int i = 0;
+ for (Slot entry : entries) {
+ EntryStack<?> currentEntry = entry.getCurrentEntry();
+ extraData[i++] = ((BatchedEntryRenderer<Object, Object>) currentEntry.getRenderer()).getExtraData(currentEntry.cast());
+ }
+ renderBatched(debugTime, size, time, matrices, mouseX, mouseY, delta, entries, extraData);
+ return;
+ }
+ }
+ renderSlow(debugTime, size, time, matrices, mouseX, mouseY, delta, entries);
+ }
+
+ private static void renderBatched(boolean debugTime, MutableInt size, MutableLong time, PoseStack matrices, int mouseX, int mouseY, float delta, Iterable<? extends Slot> entries, Object[] extraData) {
+ Slot firstWidget = Iterables.getFirst(entries, null);
+ if (firstWidget == null) return;
+ @SuppressWarnings("rawtypes")
+ EntryStack first = firstWidget.getCurrentEntry();
+ EntryRenderer<?> renderer = first.getRenderer();
+ BatchedEntryRenderer<?, Object> firstRenderer = (BatchedEntryRenderer<?, Object>) renderer;
+ matrices = firstRenderer.batchModifyMatrices(matrices);
+ long l = debugTime ? System.nanoTime() : 0;
+ MultiBufferSource.BufferSource immediate = Minecraft.getInstance().renderBuffers().bufferSource();
+ int i = 0;
+ for (Slot entry : entries) {
+ try {
+ entry.drawBackground(matrices, mouseX, mouseY, delta);
+ } catch (Throwable throwable) {
+ CrashReport report = CrashReportUtils.essential(throwable, "Rendering entry background");
+ CrashReportUtils.renderer(report, entry);
+ CrashReportUtils.catchReport(report);
+ return;
+ }
+ }
+ firstRenderer.startBatch(first, extraData[0], matrices, delta);
+ for (Slot entry : entries) {
+ try {
+ @SuppressWarnings("rawtypes")
+ EntryStack currentEntry = entry.getCurrentEntry();
+ currentEntry.setZ(100);
+ firstRenderer.renderBase(currentEntry, extraData[i++], matrices, immediate, entry.getInnerBounds(), mouseX, mouseY, delta);
+ if (debugTime && !currentEntry.isEmpty()) size.increment();
+ } catch (Throwable throwable) {
+ CrashReport report = CrashReportUtils.essential(throwable, "Rendering entry base");
+ CrashReportUtils.renderer(report, entry);
+ CrashReportUtils.catchReport(report);
+ return;
+ }
+ }
+ immediate.endBatch();
+ firstRenderer.afterBase(first, extraData[0], matrices, delta);
+ i = 0;
+ for (Slot entry : entries) {
+ try {
+ @SuppressWarnings("rawtypes")
+ EntryStack currentEntry = entry.getCurrentEntry();
+ firstRenderer.renderOverlay(currentEntry, extraData[i++], matrices, immediate, entry.getInnerBounds(), mouseX, mouseY, delta);
+ } catch (Throwable throwable) {
+ CrashReport report = CrashReportUtils.essential(throwable, "Rendering entry base");
+ CrashReportUtils.renderer(report, entry);
+ CrashReportUtils.catchReport(report);
+ return;
+ }
+ }
+ immediate.endBatch();
+ for (Slot entry : entries) {
+ try {
+ if (entry.containsMouse(mouseX, mouseY)) {
+ Tooltip tooltip = entry.getCurrentTooltip(TooltipContext.of(new Point(mouseX, mouseY)));
+ if (tooltip != null) {
+ tooltip.queue();
+ }
+
+ if (entry.isHighlightEnabled()) {
+ entry.drawHighlighted(matrices, mouseX, mouseY, delta);
+ }
+ }
+
+ entry.drawExtra(matrices, mouseX, mouseY, delta);
+ } catch (Throwable throwable) {
+ CrashReport report = CrashReportUtils.essential(throwable, "Rendering entry extra");
+ CrashReportUtils.renderer(report, entry);
+ CrashReportUtils.catchReport(report);
+ return;
+ }
+ }
+ if (debugTime) time.add(System.nanoTime() - l);
+ firstRenderer.endBatch(first, extraData[0], matrices, delta);
+ }
+
+ public static void renderSlow(boolean debugTime, MutableInt size, MutableLong time, PoseStack matrices, int mouseX, int mouseY, float delta, Iterable<? extends Slot> entries) {
+ for (Slot entry : entries) {
+ if (entry.getCurrentEntry().isEmpty())
+ continue;
+ try {
+ if (debugTime) {
+ size.increment();
+ long l = System.nanoTime();
+ entry.render(matrices, mouseX, mouseY, delta);
+ time.add(System.nanoTime() - l);
+ } else entry.render(matrices, mouseX, mouseY, delta);
+ } catch (Throwable throwable) {
+ CrashReport report = CrashReportUtils.essential(throwable, "Rendering entry");
+ CrashReportUtils.renderer(report, entry);
+ CrashReportUtils.catchReport(report);
+ return;
+ }
+ }
+ }
+
+ @Override
+ public List<? extends GuiEventListener> children() {
+ return null;
+ }
+
+ private class DelegatedSlotList extends AbstractList<Slot> {
+ private final List<Slot> unmodifiable = CollectionUtils.concatUnmodifiable(toRender,
+ groupingsAsList());
+
+ @Override
+ public void add(int index, Slot element) {
+ add(element);
+ }
+
+ @Override
+ public int size() {
+ return size;
+ }
+
+ @Override
+ public boolean add(Slot widget) {
+ if (fastEntryRendering) {
+ EntryStack<?> currentEntry = widget.getCurrentEntry();
+ try {
+ EntryRenderer<?> renderer = currentEntry.getRenderer();
+ if (renderer instanceof BatchedEntryRenderer) {
+ BatchedEntryRenderer<Object, Object> batchedRenderer = (BatchedEntryRenderer<Object, Object>) renderer;
+ EntryStack<Object> cast = currentEntry.cast();
+ if (batchedRenderer.isBatched(cast)) {
+ Object extraData = batchedRenderer.getExtraData(cast);
+ int hash = batchedRenderer.getBatchIdentifier(cast, widget.getBounds(), extraData)
+ ^ widget.getCurrentEntry().getType().hashCode();
+ List<Object> entries = grouping.get(hash);
+ if (entries == null) {
+ grouping.put(hash, entries = new ArrayList<>());
+ }
+ entries.add(widget);
+ entries.add(extraData);
+ size++;
+ return true;
+ }
+ }
+ } catch (Throwable throwable) {
+ CrashReport report = CrashReportUtils.essential(throwable, "Adding entry");
+ CrashReportUtils.renderer(report, currentEntry);
+ CrashReportUtils.catchReport(report);
+ return false;
+ }
+ }
+
+ addUnbatched(widget);
+ return true;
+ }
+
+ @Override
+ public Slot get(int index) {
+ return unmodifiable.get(index);
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends Slot> widgets) {
+ if (fastEntryRendering) {
+ for (Slot widget : widgets) {
+ add(widget);
+ }
+ } else {
+ addAllUnbatched(widgets);
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/BurningFireWidget.java b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/BurningFireWidget.java
new file mode 100644
index 000000000..4140de261
--- /dev/null
+++ b/runtime-frontend/widgets/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/BurningFireWidg