Files
NotEnoughItems/src/main/java/codechicken/nei/recipe/RecipePageManager.java
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

222 lines
7.1 KiB
Java
Raw Normal View History

2025-11-05 19:00:09 +02:00
package codechicken.nei.recipe;
import java.util.ArrayList;
import java.util.Collections;
2026-09-27 07:39:27 +03:00
import java.util.HashMap;
2025-11-05 19:00:09 +02:00
import java.util.List;
2026-09-27 07:39:27 +03:00
import java.util.Map;
2025-11-05 19:00:09 +02:00
2026-09-28 00:19:29 +03:00
import net.minecraft.item.ItemStack;
2025-11-05 19:00:09 +02:00
import codechicken.nei.NEIClientConfig;
import codechicken.nei.Widget;
2026-09-27 07:39:27 +03:00
import codechicken.nei.recipe.widget.RecipeWidget;
2025-11-05 19:00:09 +02:00
import codechicken.nei.scroll.ScrollContainer;
public class RecipePageManager {
private SearchRecipeHandler<?> handler;
private ScrollContainer container;
private HandlerInfo handlerInfo;
private String cacheKey = "";
private int currentPageIndex = -1;
private List<List<Widget>> pageWidgets = new ArrayList<>();
public RecipePageManager(SearchRecipeHandler<?> handler, HandlerInfo handlerInfo, ScrollContainer container) {
this.handler = handler;
this.handlerInfo = handlerInfo;
this.container = container;
rebuildPages();
}
public boolean rebuildPages() {
final String cacheKey = handlerInfo.getHandlerName() + ":"
+ getNumRecipes()
+ ":"
+ this.container.getVisibleHeight()
+ ":"
+ GuiRecipe.searchField.text();
if (cacheKey.equals(this.cacheKey)) {
return false;
}
this.cacheKey = cacheKey;
2026-09-28 00:19:29 +03:00
final List<RecipeWidget> pausedWidgets = getPausedWidgets();
2025-11-05 19:00:09 +02:00
this.pageWidgets.clear();
2026-05-06 19:31:00 +03:00
final boolean allowOverflowY = this.handlerInfo.isAllowOverflowY();
2025-11-05 19:00:09 +02:00
final int handlerHeight = this.handlerInfo.getHeight() + this.handlerInfo.getYShift();
2026-05-06 19:31:00 +03:00
final boolean multipleWidgetsAllowed = !allowOverflowY && handlerInfo.isMultipleWidgetsAllowed();
final boolean infiniteScroll = !allowOverflowY
2025-11-05 19:00:09 +02:00
&& NEIClientConfig.getBooleanSetting("inventory.guirecipe.infiniteScroll");
final int heightAvailable = this.container.getVisibleHeight();
final int width = Math.max(166, this.handlerInfo.getWidth());
final List<Integer> searchRecipes = this.handler.getFilteredRecipes();
final int numRecipes = searchRecipes.size();
2026-09-27 07:39:27 +03:00
final List<List<Integer>> groupedRecipes = new ArrayList<>();
final Map<Object, Integer> groupEndIndices = new HashMap<>();
2025-11-05 19:00:09 +02:00
List<Widget> widgets = new ArrayList<>();
int shiftY = 0;
for (int i = 0; i < numRecipes; i++) {
final int recipeIndex = searchRecipes.get(i);
2026-09-27 07:39:27 +03:00
final Object groupId = this.handler.original.getRecipeGroupId(recipeIndex);
final int groupIndex = groupId != null
? groupEndIndices.computeIfAbsent(groupId, k -> groupedRecipes.size())
: groupedRecipes.size();
if (groupedRecipes.size() <= groupIndex) {
groupedRecipes.add(new ArrayList<>());
}
groupedRecipes.get(groupIndex).add(recipeIndex);
}
for (int groupIndex = 0; groupIndex < groupedRecipes.size(); groupIndex++) {
final RecipeWidget widget = new RecipeWidget(this.handler.original, groupedRecipes.get(groupIndex));
2026-09-28 00:19:29 +03:00
// keep the pause of the rebuilt widgets
for (RecipeWidget paused : pausedWidgets) {
final int pausedIndex = paused.getRecipeHandlerRef().recipeIndex;
if (widget.containsRecipeIndex(pausedIndex)) {
widget.pinRecipe(pausedIndex, paused.getPinnedIngredients());
}
}
2025-11-05 19:00:09 +02:00
widget.w = width;
2026-05-06 19:31:00 +03:00
if (allowOverflowY) {
2025-11-05 19:00:09 +02:00
widget.h = Math.min(handlerHeight, heightAvailable);
}
if (!widgets.isEmpty()
&& (!multipleWidgetsAllowed || !infiniteScroll && shiftY + widget.h > heightAvailable)) {
this.pageWidgets.add(widgets);
widgets = new ArrayList<>();
shiftY = 0;
}
widgets.add(widget);
shiftY += widget.h;
}
if (!widgets.isEmpty()) {
this.pageWidgets.add(widgets);
}
changePage(0);
return true;
}
public boolean isMultipleWidgetsAllowed() {
2026-05-06 19:31:00 +03:00
return !this.handlerInfo.isAllowOverflowY() && this.handlerInfo.isMultipleWidgetsAllowed();
2025-11-05 19:00:09 +02:00
}
public int getNumRecipes() {
return this.handler.numRecipes();
}
public int getCurrentPageIndex() {
return this.currentPageIndex;
}
public int getNumPages() {
return this.pageWidgets.size();
}
public void changePage(int delta) {
final int numPages = getNumPages();
final int page = numPages > 0 ? (numPages + Math.max(0, this.currentPageIndex) + delta) % numPages : 0;
if (this.currentPageIndex == page) {
return;
}
this.currentPageIndex = page;
this.container.setVerticalScrollOffset(0);
}
2026-09-27 07:39:27 +03:00
public boolean gotoRecipeIndex(int recipeIndex) {
2025-11-05 19:00:09 +02:00
2026-09-27 07:39:27 +03:00
for (int page = 0; page < this.pageWidgets.size(); page++) {
for (Widget widget : this.pageWidgets.get(page)) {
if (widget instanceof RecipeWidget recipeWidget && recipeWidget.containsRecipeIndex(recipeIndex)) {
changePage(page - this.currentPageIndex);
return true;
}
2025-11-05 19:00:09 +02:00
}
}
2026-09-28 00:19:29 +03:00
return false;
}
private List<RecipeWidget> getPausedWidgets() {
final List<RecipeWidget> paused = new ArrayList<>();
for (List<Widget> widgets : this.pageWidgets) {
for (Widget widget : widgets) {
if (widget instanceof RecipeWidget recipeWidget && recipeWidget.isPaused()) {
paused.add(recipeWidget);
}
}
}
return paused;
}
public boolean pinRecipe(int recipeIndex, List<ItemStack> ingredients) {
for (List<Widget> widgets : this.pageWidgets) {
for (Widget widget : widgets) {
if (widget instanceof RecipeWidget recipeWidget && recipeWidget.containsRecipeIndex(recipeIndex)) {
return recipeWidget.pinRecipe(recipeIndex, ingredients);
}
}
}
2026-09-27 07:39:27 +03:00
return false;
2025-11-05 19:00:09 +02:00
}
public List<Widget> getCurrentPageWidgets() {
if (this.pageWidgets.isEmpty()) {
return Collections.emptyList();
}
List<Widget> currentWidgets = this.pageWidgets.get(this.currentPageIndex);
int shiftY = 0;
for (Widget widget : currentWidgets) {
2026-09-27 07:39:27 +03:00
if (widget instanceof RecipeWidget recipeWidget) {
2026-01-19 08:47:05 +02:00
recipeWidget.setLocation(2, shiftY);
2025-11-05 19:00:09 +02:00
}
shiftY += widget.h;
}
return currentWidgets;
}
public List<Integer> getRecipeIndices() {
2026-09-27 07:39:27 +03:00
if (this.pageWidgets.isEmpty()) {
return Collections.emptyList();
}
final List<Integer> recipeIndices = new ArrayList<>();
for (Widget widget : this.pageWidgets.get(this.currentPageIndex)) {
if (widget instanceof RecipeWidget recipeWidget) {
recipeIndices.add(recipeWidget.getRecipeHandlerRef().recipeIndex);
}
}
return recipeIndices;
2025-11-05 19:00:09 +02:00
}
}