aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2023-03-16 23:01:27 +0800
committershedaniel <daniel@shedaniel.me>2023-03-16 23:01:27 +0800
commit1e384a7f0906bc7526ff9596965d76b5bc8fc599 (patch)
tree341e6d811207d416e772f620eef5343c6ddcc0e9
parentc871bc0a460b8b22ea49d12cc12f9775d67ccd8e (diff)
parent8e0aafdf9e16688117bd57e14824d664eb816fa0 (diff)
downloadRoughlyEnoughItems-1e384a7f0906bc7526ff9596965d76b5bc8fc599.tar.gz
RoughlyEnoughItems-1e384a7f0906bc7526ff9596965d76b5bc8fc599.tar.bz2
RoughlyEnoughItems-1e384a7f0906bc7526ff9596965d76b5bc8fc599.zip
Merge remote-tracking branch 'origin/10.x-1.19.3' into 11.x-1.19.4
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringScreen.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRuleType.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchedEntryRendererManager.java50
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/CollapsedEntriesBorderRenderer.java171
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListStackEntry.java11
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/PaginatedEntryListWidget.java19
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/ScrolledEntryListWidget.java16
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/EntryStacksRegionWidget.java2
8 files changed, 246 insertions, 27 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringScreen.java
index 3c9837db0..477fb0d00 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringScreen.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringScreen.java
@@ -232,7 +232,7 @@ public class FilteringScreen extends Screen {
int skip = Math.max(0, Mth.floor(scrolling.scrollAmount() / (float) entrySize()));
int nextIndex = skip * innerBounds.width / entrySize();
int i = nextIndex;
- BatchedEntryRendererManager manager = new BatchedEntryRendererManager();
+ BatchedEntryRendererManager<FilteringListEntry> manager = new BatchedEntryRendererManager<>();
for (; i < entryStacks.size(); i++) {
EntryStack<?> stack = entryStacks.get(i);
FilteringListEntry entry = entries.get(nextIndex);
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRuleType.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRuleType.java
index a78917fef..9ffb425d8 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRuleType.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRuleType.java
@@ -146,7 +146,7 @@ public enum SearchFilteringRuleType implements FilteringRuleType<SearchFiltering
@Override
public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) {
- BatchedEntryRendererManager manager = new BatchedEntryRendererManager();
+ BatchedEntryRendererManager<EntryWidget> manager = new BatchedEntryRendererManager<>();
int entrySize = entrySize();
int width = entryWidth / entrySize;
int i = 0;
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchedEntryRendererManager.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchedEntryRendererManager.java
index 11fff3ddf..78775c525 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchedEntryRendererManager.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchedEntryRendererManager.java
@@ -25,6 +25,7 @@ package me.shedaniel.rei.impl.client.gui.widget;
import com.google.common.collect.AbstractIterator;
import com.google.common.collect.Iterables;
+import com.google.common.collect.Iterators;
import com.mojang.blaze3d.vertex.PoseStack;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
@@ -32,26 +33,29 @@ 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.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.renderer.MultiBufferSource;
import org.apache.commons.lang3.mutable.MutableInt;
import org.apache.commons.lang3.mutable.MutableLong;
+import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Iterator;
import java.util.List;
-public class BatchedEntryRendererManager {
- private boolean fastEntryRendering = ConfigObject.getInstance().doesFastEntryRendering();
- private Int2ObjectMap<List<Object>> grouping = new Int2ObjectOpenHashMap<>();
- private List<EntryWidget> toRender = new ArrayList<>();
+public class BatchedEntryRendererManager<T extends EntryWidget> implements Iterable<T> {
+ private final boolean fastEntryRendering = ConfigObject.getInstance().doesFastEntryRendering();
+ private final Int2ObjectMap<List<Object>> grouping = new Int2ObjectOpenHashMap<>();
+ private final List<T> toRender = new ArrayList<>();
public BatchedEntryRendererManager() {
}
- public BatchedEntryRendererManager(Collection<? extends EntryWidget> widgets) {
+ public BatchedEntryRendererManager(Collection<? extends T> widgets) {
addAll(widgets);
}
@@ -59,9 +63,9 @@ public class BatchedEntryRendererManager {
return fastEntryRendering;
}
- public void addAll(Collection<? extends EntryWidget> widgets) {
+ public void addAll(Collection<? extends T> widgets) {
if (fastEntryRendering) {
- for (EntryWidget widget : widgets) {
+ for (T widget : widgets) {
add(widget);
}
} else {
@@ -69,7 +73,7 @@ public class BatchedEntryRendererManager {
}
}
- public void add(EntryWidget widget) {
+ public void add(T widget) {
if (fastEntryRendering) {
EntryStack<?> currentEntry = widget.getCurrentEntry();
try {
@@ -101,11 +105,11 @@ public class BatchedEntryRendererManager {
addSlow(widget);
}
- public void addAllSlow(Collection<? extends EntryWidget> widgets) {
+ public void addAllSlow(Collection<? extends T> widgets) {
toRender.addAll(widgets);
}
- public void addSlow(EntryWidget widget) {
+ public void addSlow(T widget) {
toRender.add(widget);
}
@@ -120,15 +124,15 @@ public class BatchedEntryRendererManager {
for (int i = 0; i < extraData.length; i++) {
extraData[i] = entries.get(i * 2 + 1);
}
- renderBatched(debugTime, size, time, matrices, mouseX, mouseY, delta, () -> new AbstractIterator<>() {
+ renderBatched(debugTime, size, time, matrices, mouseX, mouseY, delta, () -> new AbstractIterator<T>() {
public int i = 0;
@Override
- protected EntryWidget computeNext() {
+ protected T computeNext() {
if (i >= entries.size()) {
return endOfData();
}
- EntryWidget widget = (EntryWidget) entries.get(i);
+ T widget = (T) entries.get(i);
i += 2;
return widget;
}
@@ -252,4 +256,24 @@ public class BatchedEntryRendererManager {
}
}
}
+
+ @NotNull
+ @Override
+ public Iterator<T> iterator() {
+ return Iterators.concat(toRender.iterator(), Iterators.concat(
+ CollectionUtils.<List<Object>, Iterator<T>>map(grouping.values(), entries -> new AbstractIterator<>() {
+ public int i = 0;
+
+ @Override
+ protected T computeNext() {
+ if (i >= entries.size()) {
+ return endOfData();
+ }
+ T widget = (T) entries.get(i);
+ i += 2;
+ return widget;
+ }
+ }).iterator()
+ ));
+ }
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/CollapsedEntriesBorderRenderer.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/CollapsedEntriesBorderRenderer.java
new file mode 100644
index 000000000..18e8d7e90
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/CollapsedEntriesBorderRenderer.java
@@ -0,0 +1,171 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021, 2022, 2023 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.entrylist;
+
+import com.mojang.blaze3d.vertex.PoseStack;
+import it.unimi.dsi.fastutil.longs.*;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import me.shedaniel.math.Rectangle;
+import me.shedaniel.rei.impl.common.entry.type.collapsed.CollapsedStack;
+import net.minecraft.client.gui.GuiComponent;
+
+import static me.shedaniel.rei.impl.client.gui.widget.entrylist.EntryListWidget.entrySize;
+
+public class CollapsedEntriesBorderRenderer extends GuiComponent {
+ private static final int TOP = 0b00;
+ private static final int BOTTOM = 0b01;
+ private static final int LEFT = 0b10;
+ private static final int RIGHT = 0b11;
+ private static final int TOP_O = 0b100;
+ private static final int BOTTOM_O = 0b101;
+ private static final int LEFT_O = 0b110;
+ private static final int RIGHT_O = 0b111;
+
+ public void render(PoseStack matrices, Iterable<EntryListStackEntry> entries, Object2IntMap<CollapsedStack> collapsedStackIndicesGlobal) {
+ if (collapsedStackIndicesGlobal.isEmpty()) return;
+ LongSet edgeSet = new LongOpenHashSet();
+ int entrySize = entrySize();
+ // bit 0-1: direction
+ // bit 2 occupied: has edge
+ // bit 3-14: collapsed stack index
+ // bit 15-30: y
+ // bit 31-46: x
+ for (EntryListStackEntry entry : entries) {
+ if (entry.getCollapsedStack() != null && entry.getCollapsedStack().isExpanded()) {
+ Rectangle entryBounds = entry.getBounds();
+ int collapsedStackIndices = collapsedStackIndicesGlobal.getInt(entry.getCollapsedStack());
+ long base = getPackedLong(entryBounds.getCenterX() + 100, entryBounds.getCenterY() + 100, collapsedStackIndices, 0, false);
+ if (!edgeSet.add(base | TOP)) edgeSet.add(base | TOP_O);
+ if (!edgeSet.add(base | BOTTOM)) edgeSet.add(base | BOTTOM_O);
+ if (!edgeSet.add(base | LEFT)) edgeSet.add(base | LEFT_O);
+ if (!edgeSet.add(base | RIGHT)) edgeSet.add(base | RIGHT_O);
+ // to left (base - ((long) entrySize << 31)) | RIGHT)
+ long nL = withDirD(shiftLongX(base, -entrySize), RIGHT, false);
+ if (edgeSet.contains(nL)) {
+ edgeSet.add(occupiedLong(nL));
+ edgeSet.add(base | LEFT_O);
+ }
+ // to right
+ nL = withDirD(shiftLongX(base, entrySize), LEFT, false);
+ if (edgeSet.contains(nL)) {
+ edgeSet.add(occupiedLong(nL));
+ edgeSet.add(base | RIGHT_O);
+ }
+ // to top
+ nL = withDirD(shiftLongY(base, -entrySize), BOTTOM, false);
+ if (edgeSet.contains(nL)) {
+ edgeSet.add(occupiedLong(nL));
+ edgeSet.add(base | TOP_O);
+ }
+ // to bottom
+ nL = withDirD(shiftLongY(base, entrySize), TOP, false);
+ if (edgeSet.contains(nL)) {
+ edgeSet.add(occupiedLong(nL));
+ edgeSet.add(base | BOTTOM_O);
+ }
+ }
+ }
+
+ LongIterator iterator = edgeSet.iterator();
+ LongList toRemove = new LongArrayList();
+ while (iterator.hasNext()) {
+ long l = iterator.nextLong();
+ if ((l & 0b100) != 0) {
+ toRemove.add(l);
+ toRemove.add(l & ~0b100);
+ }
+ }
+ edgeSet.removeAll(toRemove);
+
+ matrices.pushPose();
+ matrices.translate(-100, -100, 0);
+
+ iterator = edgeSet.iterator();
+ while (iterator.hasNext()) {
+ long l = iterator.nextLong();
+ int x = (int) (l >> 31);
+ int y = (int) ((l >> 15) & 0xFFFF);
+ int collapsedStackIndices = (int) ((l >> 3) & 0b111111111111);
+ int x1 = x - entrySize / 2;
+ int y1 = y - entrySize / 2;
+ int x2 = x1 + entrySize;
+ int y2 = y1 + entrySize;
+ int direction = (int) (l & RIGHT);
+ switch (direction) {
+ case 0 -> { // top
+ int fStart = edgeSet.contains(shiftLongX(l, -entrySize)) || edgeSet.contains(withDirD(l, LEFT, false)) ? 0 : 1;
+ int fEnd = edgeSet.contains(shiftLongX(l, entrySize)) || edgeSet.contains(withDirD(l, RIGHT, false)) ? 0 : 1;
+ if (fStart == 1 && edgeSet.contains(getPackedLong(x - entrySize, y - entrySize, collapsedStackIndices, RIGHT, false))) fStart = -1;
+ if (fEnd == 1 && edgeSet.contains(getPackedLong(x + entrySize, y - entrySize, collapsedStackIndices, LEFT, false))) fEnd = -1;
+ fillGradient(matrices, x1 + fStart, y1, x2 - fEnd, y1 + 1, 0x67FFFFFF, 0x67FFFFFF);
+ }
+ case 1 -> { // bottom
+ int fStart = edgeSet.contains(shiftLongX(l, -entrySize)) || edgeSet.contains(withDirD(l, LEFT, false)) ? 0 : 1;
+ int fEnd = edgeSet.contains(shiftLongX(l, entrySize)) || edgeSet.contains(withDirD(l, RIGHT, false)) ? 0 : 1;
+ if (fStart == 1 && edgeSet.contains(getPackedLong(x - entrySize, y + entrySize, collapsedStackIndices, RIGHT, false))) fStart = -1;
+ if (fEnd == 1 && edgeSet.contains(getPackedLong(x + entrySize, y + entrySize, collapsedStackIndices, LEFT, false))) fEnd = -1;
+ fillGradient(matrices, x1 + fStart, y2 - 1, x2 - fEnd, y2, 0x67FFFFFF, 0x67FFFFFF);
+ }
+ case 2 -> { // left
+ int fStart = edgeSet.contains(shiftLongY(l, -entrySize)) ? 0 : 1;
+ int fEnd = edgeSet.contains(shiftLongY(l, entrySize)) ? 0 : 1;
+ if (fStart == 1 && edgeSet.contains(getPackedLong(x - entrySize, y - entrySize, collapsedStackIndices, BOTTOM, false))) fStart = 0;
+ if (fEnd == 1 && edgeSet.contains(getPackedLong(x - entrySize, y + entrySize, collapsedStackIndices, TOP, false))) fEnd = 0;
+ fillGradient(matrices, x1, y1 + fStart, x1 + 1, y2 - fEnd, 0x67FFFFFF, 0x67FFFFFF);
+ }
+ case 3 -> { // right
+ int fStart = edgeSet.contains(shiftLongY(l, -entrySize)) ? 0 : 1;
+ int fEnd = edgeSet.contains(shiftLongY(l, entrySize)) ? 0 : 1;
+ if (fStart == 1 && edgeSet.contains(getPackedLong(x + entrySize, y - entrySize, collapsedStackIndices, BOTTOM, false))) fStart = 0;
+ if (fEnd == 1 && edgeSet.contains(getPackedLong(x + entrySize, y + entrySize, collapsedStackIndices, TOP, false))) fEnd = 0;
+ fillGradient(matrices, x2 - 1, y1 + fStart, x2, y2 - fEnd, 0x67FFFFFF, 0x67FFFFFF);
+ }
+ }
+ }
+
+ matrices.popPose();
+ }
+
+ private static long getPackedLong(int x, int y, int collapsedStackIndices, int direction, boolean occupied) {
+ long l = ((long) x << 31) | ((long) y << 15) | ((long) collapsedStackIndices << 3) | direction;
+ if (occupied) l |= 0b100;
+ return l;
+ }
+
+ private static long shiftLongX(long l, int dX) {
+ return l + ((long) dX << 31);
+ }
+
+ private static long shiftLongY(long l, int dX) {
+ return l + ((long) dX << 15);
+ }
+
+ private static long withDirD(long l, int dir, boolean occupied) {
+ return (l & ~RIGHT_O) | dir | (occupied ? 0b100 : 0);
+ }
+
+ private static long occupiedLong(long l) {
+ return l | 0b100;
+ }
+}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListStackEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListStackEntry.java
index 8f8662bc7..729dbb834 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListStackEntry.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListStackEntry.java
@@ -110,8 +110,15 @@ public class EntryListStackEntry extends DisplayedEntryWidget {
if (collapsedStack != null) {
int entrySize = entrySize();
- fillGradient(matrices, bounds.getCenterX() - entrySize / 2, bounds.getCenterY() - entrySize / 2,
- bounds.getCenterX() + entrySize / 2 + 1, bounds.getCenterY() + entrySize / 2 + 1, 0x34FFFFFF, 0x34FFFFFF);
+ int x1 = bounds.getCenterX() - entrySize / 2;
+ int y1 = bounds.getCenterY() - entrySize / 2;
+ int x2 = x1 + entrySize;
+ int y2 = y1 + entrySize;
+ if (collapsedStack.isExpanded()) {
+ fillGradient(matrices, x1, y1, x2, y2, 0x34FFFFFF, 0x34FFFFFF);
+ } else {
+ fillGradient(matrices, x1, y1, x2, y2, 0x53FFFFFF, 0x53FFFFFF);
+ }
}
super.drawBackground(matrices, mouseX, mouseY, delta);
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/PaginatedEntryListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/PaginatedEntryListWidget.java
index 6954c895d..258140201 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/PaginatedEntryListWidget.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/PaginatedEntryListWidget.java
@@ -27,6 +27,8 @@ import com.google.common.collect.Lists;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import me.shedaniel.math.Point;
import me.shedaniel.math.Rectangle;
import me.shedaniel.rei.api.client.config.ConfigObject;
@@ -51,16 +53,14 @@ import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.minecraft.util.Mth;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Random;
+import java.util.*;
import java.util.stream.Stream;
public class PaginatedEntryListWidget extends CollapsingEntryListWidget {
private Button leftButton, rightButton, changelogButton;
private List<Widget> additionalWidgets;
private List</*EntryStack<?> | EntryIngredient*/ Object> stacks = new ArrayList<>();
+ private Object2IntMap<CollapsedStack> collapsedStackIndices = new Object2IntOpenHashMap<>();
protected List<EntryListStackEntry> entries = Collections.emptyList();
private int page;
@@ -94,7 +94,7 @@ public class PaginatedEntryListWidget extends CollapsingEntryListWidget {
}
}
- BatchedEntryRendererManager manager = new BatchedEntryRendererManager();
+ BatchedEntryRendererManager<EntryListStackEntry> manager = new BatchedEntryRendererManager<>();
if (manager.isFastEntryRendering()) {
for (EntryListStackEntry entry : entries) {
CollapsedStack collapsedStack = entry.getCollapsedStack();
@@ -109,6 +109,8 @@ public class PaginatedEntryListWidget extends CollapsingEntryListWidget {
}
manager.render(debugger.debugTime, debugger.size, debugger.time, matrices, mouseX, mouseY, delta);
+ new CollapsedEntriesBorderRenderer().render(matrices, entries, collapsedStackIndices);
+
for (Widget widget : additionalWidgets) {
widget.render(matrices, mouseX, mouseY, delta);
}
@@ -137,6 +139,7 @@ public class PaginatedEntryListWidget extends CollapsingEntryListWidget {
int skip = Math.max(0, page * entries.size());
List</*EntryStack<?> | List<EntryStack<?>>*/ Object> subList = stacks.stream().skip(skip).limit(Math.max(0, entries.size() - Math.max(0, -page * entries.size()))).toList();
Int2ObjectMap<CollapsedStack> indexedCollapsedStack = getCollapsedStackIndexed();
+ Set<CollapsedStack> collapsedStacks = new LinkedHashSet<>();
for (int i = 0; i < subList.size(); i++) {
/*EntryStack<?> | List<EntryStack<?>>*/
Object stack = subList.get(i);
@@ -152,11 +155,17 @@ public class PaginatedEntryListWidget extends CollapsingEntryListWidget {
CollapsedStack collapsedStack = indexedCollapsedStack.get(i + skip);
if (collapsedStack != null && collapsedStack.getIngredient().size() > 1) {
entry.collapsed(collapsedStack);
+ collapsedStacks.add(collapsedStack);
} else {
entry.collapsed(null);
}
}
this.entries = entries;
+ this.collapsedStackIndices = new Object2IntOpenHashMap<>();
+ int index = 0;
+ for (CollapsedStack stack : collapsedStacks) {
+ collapsedStackIndices.put(stack, index++);
+ }
}
@Override
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/ScrolledEntryListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/ScrolledEntryListWidget.java
index ac057a33c..9dc466cf9 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/ScrolledEntryListWidget.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/ScrolledEntryListWidget.java
@@ -27,6 +27,8 @@ import com.google.common.base.Predicates;
import com.google.common.collect.Lists;
import com.mojang.blaze3d.vertex.PoseStack;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import me.shedaniel.clothconfig2.ClothConfigInitializer;
import me.shedaniel.clothconfig2.api.ScissorsHandler;
import me.shedaniel.clothconfig2.api.scroll.ScrollingContainer;
@@ -39,9 +41,7 @@ import me.shedaniel.rei.impl.common.entry.type.collapsed.CollapsedStack;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.util.Mth;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
import java.util.stream.Stream;
public class ScrolledEntryListWidget extends CollapsingEntryListWidget {
@@ -68,8 +68,11 @@ public class ScrolledEntryListWidget extends CollapsingEntryListWidget {
int skip = Math.max(0, Mth.floor(scrolling.scrollAmount() / (float) entrySize));
int nextIndex = skip * innerBounds.width / entrySize;
this.blockedCount = 0;
- BatchedEntryRendererManager helper = new BatchedEntryRendererManager();
+ BatchedEntryRendererManager<EntryListStackEntry> helper = new BatchedEntryRendererManager<>();
Int2ObjectMap<CollapsedStack> indexedCollapsedStack = getCollapsedStackIndexed();
+ int collapsedStacksIndex = 0;
+ Object2IntMap<CollapsedStack> collapsedStackIndices = new Object2IntOpenHashMap<>();
+ collapsedStackIndices.defaultReturnValue(-1);
int i = nextIndex;
for (int cont = nextIndex; cont < entries.size(); cont++) {
@@ -100,6 +103,9 @@ public class ScrolledEntryListWidget extends CollapsingEntryListWidget {
CollapsedStack collapsedStack = indexedCollapsedStack.get(i - 1);
if (collapsedStack != null && collapsedStack.getIngredient().size() > 1) {
entry.collapsed(collapsedStack);
+ if (!collapsedStackIndices.containsKey(collapsedStack)) {
+ collapsedStackIndices.put(collapsedStack, collapsedStacksIndex++);
+ }
} else {
entry.collapsed(null);
}
@@ -109,6 +115,8 @@ public class ScrolledEntryListWidget extends CollapsingEntryListWidget {
}
helper.render(debugger.debugTime, debugger.size, debugger.time, matrices, mouseX, mouseY, delta);
+
+ new CollapsedEntriesBorderRenderer().render(matrices, helper, collapsedStackIndices);
scrolling.updatePosition(delta);
ScissorsHandler.INSTANCE.removeLastScissor();
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/EntryStacksRegionWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/EntryStacksRegionWidget.java
index 4041741d8..de91f10b5 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/EntryStacksRegionWidget.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/EntryStacksRegionWidget.java
@@ -126,7 +126,7 @@ public class EntryStacksRegionWidget<T extends RegionEntry<T>> extends WidgetWit
Stream<RegionEntryWidget<T>> entryStream = this.entriesList.stream()
.filter(entry -> entry.getBounds().getMaxY() >= this.bounds.getY() && entry.getBounds().y <= this.bounds.getMaxY());
- new BatchedEntryRendererManager(entryStream.collect(Collectors.toList()))
+ new BatchedEntryRendererManager<>(entryStream.collect(Collectors.toList()))
.render(poses, mouseX, mouseY, delta);
updatePosition(delta);