Implement Dynamic Handler Height (#792)

This commit is contained in:
slprime authored and GitHub committed 2025-11-05 19:00:09 +02:00
1 parent a186f69444
commit 667c8cb5b6
9 files changed
+429 -319

No files matched your search

@@ -86,13 +86,14 @@ public class IMCHandler {
info.setYShift(yShift);
try {
final int imageHeight = tag.hasKey("handlerHeight") ? tag.getInteger("handlerHeight")
final int handlerHeight = tag.hasKey("handlerHeight") ? tag.getInteger("handlerHeight")
: HandlerInfo.DEFAULT_HEIGHT;
final int imageWidth = tag.hasKey("handlerWidth") ? tag.getInteger("handlerWidth")
final int handlerWidth = tag.hasKey("handlerWidth") ? tag.getInteger("handlerWidth")
: HandlerInfo.DEFAULT_WIDTH;
final int maxRecipesPerPage = tag.hasKey("maxRecipesPerPage") ? tag.getInteger("maxRecipesPerPage")
: HandlerInfo.DEFAULT_MAX_PER_PAGE;
info.setHandlerDimensions(imageHeight, imageWidth, maxRecipesPerPage);
final boolean multipleWidgetsAllowed = tag.hasKey("multipleWidgetsAllowed")
? tag.getBoolean("multipleWidgetsAllowed")
: tag.hasKey("maxRecipesPerPage") && tag.getInteger("maxRecipesPerPage") > 1;
info.setHandlerDimensions(handlerWidth, handlerHeight, multipleWidgetsAllowed);
} catch (NumberFormatException ignored) {
NEIClientConfig.logger.info("Error setting handler dimensions for {}", handler);
}
@@ -125,7 +125,7 @@ public class DebugHandlerWidget extends Widget implements IContainerInputHandler
private IntegerField yShift;
private IntegerField handlerHeight;
private IntegerField handlerWidth;
private IntegerField maxRecipesPerPage;
private Button multipleWidgetsAllowed;
private Button useCustomScroll;
private Point dragPoint = null;
@@ -166,15 +166,27 @@ public class DebugHandlerWidget extends Widget implements IContainerInputHandler
}
};
this.maxRecipesPerPage = new IntegerField("maxRecipesPerPage", HandlerInfo.DEFAULT_MAX_PER_PAGE) {
this.multipleWidgetsAllowed = new Button() {
{
this.h = LINE_HEIGHT;
this.z = 2;
}
public String getRenderLabel() {
return handlerInfo.isMultipleWidgetsAllowed() ? "On" : "Off";
}
@Override
public void onTextChange(String oldText) {
if (getInteger() != handlerInfo.getMaxRecipesPerPage()) {
handlerInfo.setHandlerDimensions(handlerInfo.getHeight(), handlerInfo.getWidth(), getInteger());
updatePatch(4, getInteger(), this.defaultValue);
}
public boolean onButtonPress(boolean rightclick) {
handlerInfo.setHandlerDimensions(
handlerInfo.getWidth(),
handlerInfo.getHeight(),
!handlerInfo.isMultipleWidgetsAllowed());
updatePatch(4, handlerInfo.isMultipleWidgetsAllowed() ? 1 : 0, 1);
return true;
}
};
this.handlerHeight = new IntegerField("handlerHeight", HandlerInfo.DEFAULT_HEIGHT) {
@@ -189,9 +201,9 @@ public class DebugHandlerWidget extends Widget implements IContainerInputHandler
public void onTextChange(String oldText) {
if (getInteger() != handlerInfo.getHeight()) {
handlerInfo.setHandlerDimensions(
getInteger(),
handlerInfo.getWidth(),
handlerInfo.getMaxRecipesPerPage());
getInteger(),
handlerInfo.isMultipleWidgetsAllowed());
updatePatch(2, getInteger(), this.defaultValue);
}
}
@@ -203,9 +215,9 @@ public class DebugHandlerWidget extends Widget implements IContainerInputHandler
public void onTextChange(String oldText) {
if (getInteger() != handlerInfo.getWidth()) {
handlerInfo.setHandlerDimensions(
handlerInfo.getHeight(),
getInteger(),
handlerInfo.getMaxRecipesPerPage());
handlerInfo.getHeight(),
handlerInfo.isMultipleWidgetsAllowed());
updatePatch(3, getInteger(), this.defaultValue);
}
}
@@ -327,7 +339,7 @@ public class DebugHandlerWidget extends Widget implements IContainerInputHandler
drawControl("yShift", this.yShift, topShift, spaceWidth);
topShift += LINE_HEIGHT;
drawControl("Per Page", this.maxRecipesPerPage, topShift, spaceWidth);
drawControl("Multi Widgets", this.multipleWidgetsAllowed, topShift, spaceWidth);
topShift += LINE_HEIGHT;
drawControl("Height", this.handlerHeight, topShift, spaceWidth);
@@ -364,7 +376,7 @@ public class DebugHandlerWidget extends Widget implements IContainerInputHandler
LayoutManager.addWidget(this.yShift);
LayoutManager.addWidget(this.handlerHeight);
LayoutManager.addWidget(this.handlerWidth);
LayoutManager.addWidget(this.maxRecipesPerPage);
LayoutManager.addWidget(this.multipleWidgetsAllowed);
LayoutManager.addWidget(this.useCustomScroll);
}
}
@@ -383,7 +395,6 @@ public class DebugHandlerWidget extends Widget implements IContainerInputHandler
this.yShift.setText(String.valueOf(this.handlerInfo.getYShift()));
this.handlerHeight.setText(String.valueOf(this.handlerInfo.getHeight()));
this.handlerWidth.setText(String.valueOf(this.handlerInfo.getWidth()));
this.maxRecipesPerPage.setText(String.valueOf(this.handlerInfo.getMaxRecipesPerPage()));
}
} else {
@@ -467,8 +478,7 @@ public class DebugHandlerWidget extends Widget implements IContainerInputHandler
} else if (this.handler != null) {
return this.order.focused() || this.yShift.focused()
|| this.handlerHeight.focused()
|| this.handlerWidth.focused()
|| this.maxRecipesPerPage.focused();
|| this.handlerWidth.focused();
}
return false;
@@ -528,6 +538,10 @@ public class DebugHandlerWidget extends Widget implements IContainerInputHandler
widget.h,
COLORS[widget.handlerRef.recipeIndex % COLORS.length]);
// center cross
GuiDraw.drawRect(widget.x + widget.w / 2 - 1, widget.y, 1, widget.h, 0x88ffffff);
GuiDraw.drawRect(widget.x, widget.y + widget.h / 2 - 1, widget.w, 1, 0x88ffffff);
// blue-line-top (grid-top)
GuiDraw.drawRect(widget.x + 14, widget.y + 5, widget.w - 38, 1, 0xff0000aa);
@@ -592,12 +606,14 @@ public class DebugHandlerWidget extends Widget implements IContainerInputHandler
final int yShift = intOrDefault(parts[1], info.getYShift());
final int height = intOrDefault(parts[2], info.getHeight());
final int width = intOrDefault(parts[3], info.getWidth());
final int maxRecipesPerPage = intOrDefault(parts[4], info.getMaxRecipesPerPage());
final boolean isMultipleWidgetsAllowed = intOrDefault(
parts[4],
info.isMultipleWidgetsAllowed() ? 1 : 0) == 1;
final int order = intOrDefault(parts[5], NEIClientConfig.handlerOrdering.getOrDefault(handler, 0));
final boolean useCustomScroll = intOrDefault(parts[6], info.getUseCustomScroll() ? 1 : 0) == 1;
info.setYShift(yShift);
info.setHandlerDimensions(height, width, maxRecipesPerPage);
info.setHandlerDimensions(width, height, isMultipleWidgetsAllowed);
info.setUseCustomScroll(useCustomScroll);
NEIClientConfig.handlerOrdering.put(handler, order);
}
@@ -65,11 +65,11 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
private static final int BUTTON_WIDTH = 13;
private static final int BUTTON_HEIGHT = 12;
protected static final ScrollBar VERTICAL_SCROLLBAR = new ScrollBar().setScrollbarSize(14).setMarginStart(-6)
protected static final ScrollBar VERTICAL_SCROLLBAR = new ScrollBar().setTrackWidth(14)
.setOverflowType(OverflowType.AUTO).setScrollPlace(ScrollPlace.END)
.setTrackTexture(new DrawableBuilder("nei:textures/nei_sprites.png", 42, 90, 13, 21).build(), 9, 9)
.setThumbTexture(new DrawableBuilder("nei:textures/nei_sprites.png", 21, 96, 8, 9).build(), 3, 2)
.setThumbPadding(6);
.setThumbTexture(new DrawableBuilder("nei:textures/nei_sprites.png", 22, 96, 6, 9).build(), 3, 2)
.setThumbPadding(1, 6, 0, 6);
public static final List<IRecipeFilterProvider> recipeFilterers = new LinkedList<>();
@@ -89,12 +89,12 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
private GuiButton prevtype;
private GuiButton nexttype;
protected String recipePageCacheKey = "";
private int lastPage = -1;
private final GuiRecipeTabs recipeTabs;
private final GuiRecipeCatalyst recipeCatalyst;
private SearchRecipeHandler<H> handler;
private HandlerInfo handlerInfo;
private RecipePageManager handlerPages;
protected static final RestartableTask updateFilter = new RestartableTask("NEI Recipe Filtering") {
@@ -109,7 +109,6 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
if (GuiRecipe.searchField.text().isEmpty()) {
searchHandler.setSearchIndices(null);
guiRecipe.changePage(0);
} else {
final IRecipeFilter filter = GuiRecipe.searchField.getRecipeFilter();
final List<Integer> filtered = searchHandler.getSearchResult(filter);
@@ -120,10 +119,8 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
if (interrupted()) return;
searchHandler.setSearchIndices(filtered);
guiRecipe.changePage(0);
}
guiRecipe.recipePageCacheKey = "";
}
}
@@ -137,7 +134,8 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
@Override
protected boolean noResults() {
final GuiScreen currentScreen = NEIClientUtils.mc().currentScreen;
return !(currentScreen instanceof GuiRecipe) || ((GuiRecipe<?>) currentScreen).numRecipes() > 0;
return !(currentScreen instanceof GuiRecipe)
|| ((GuiRecipe<?>) currentScreen).handlerPages.getNumRecipes() > 0;
}
@Override
@@ -199,6 +197,36 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
this.firstGui = gui.getFirstScreen();
this.firstGuiGeneral = gui.getFirstScreenGeneral();
}
this.prevtype = new GuiNEIButton(0, 0, 0, BUTTON_WIDTH, BUTTON_HEIGHT, "<") {
@Override
public void mouseReleased(int mouseX, int mouseY) {
prevType();
}
};
this.nexttype = new GuiNEIButton(1, 0, 0, BUTTON_WIDTH, BUTTON_HEIGHT, ">") {
@Override
public void mouseReleased(int mouseX, int mouseY) {
nextType();
}
};
this.prevpage = new GuiNEIButton(2, 0, 0, BUTTON_WIDTH, BUTTON_HEIGHT, "<") {
@Override
public void mouseReleased(int mouseX, int mouseY) {
prevPage();
}
};
this.nextpage = new GuiNEIButton(3, 0, 0, BUTTON_WIDTH, BUTTON_HEIGHT, ">") {
@Override
public void mouseReleased(int mouseX, int mouseY) {
nextPage();
}
};
}
/**
@@ -272,7 +300,19 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
}
}
private ScrollContainer container = new ScrollContainer();
private ScrollContainer container = new ScrollContainer() {
@Override
public Widget getWidgetUnderMouse(int mousex, int mousey) {
if (handlerInfo.getUseCustomScroll() && !this.widgets.isEmpty()) {
return this.widgets.get(0);
}
return super.getWidgetUnderMouse(mousex, mousey);
}
};
@Override
public void initGui() {
@@ -292,35 +332,14 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
final int rightButtonX = this.guiLeft + this.xSize - BORDER_PADDING - BUTTON_WIDTH + 1;
final int leftButtonX = this.guiLeft + BORDER_PADDING;
this.prevtype = new GuiNEIButton(0, leftButtonX, guiTop + 3, BUTTON_WIDTH, BUTTON_HEIGHT, "<") {
@Override
public void mouseReleased(int mouseX, int mouseY) {
prevType();
}
};
this.nexttype = new GuiNEIButton(1, rightButtonX, guiTop + 3, BUTTON_WIDTH, BUTTON_HEIGHT, ">") {
@Override
public void mouseReleased(int mouseX, int mouseY) {
nextType();
}
};
this.prevpage = new GuiNEIButton(2, leftButtonX, guiTop + 17, BUTTON_WIDTH, BUTTON_HEIGHT, "<") {
@Override
public void mouseReleased(int mouseX, int mouseY) {
prevPage();
}
};
this.nextpage = new GuiNEIButton(3, rightButtonX, guiTop + 17, BUTTON_WIDTH, BUTTON_HEIGHT, ">") {
@Override
public void mouseReleased(int mouseX, int mouseY) {
nextPage();
}
};
this.prevtype.xPosition = leftButtonX;
this.prevtype.yPosition = guiTop + 3;
this.nexttype.xPosition = rightButtonX;
this.nexttype.yPosition = guiTop + 3;
this.prevpage.xPosition = leftButtonX;
this.prevpage.yPosition = guiTop + 17;
this.nextpage.xPosition = rightButtonX;
this.nextpage.yPosition = guiTop + 17;
this.container.x = this.guiLeft + 3;
this.container.y = this.guiTop + 32;
@@ -337,9 +356,8 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
GuiRecipe.searchField.h = 14;
this.buttonList.addAll(Arrays.asList(this.prevtype, this.nexttype, this.prevpage, this.nextpage));
this.recipePageCacheKey = "";
if (currenthandlers.size() == 1) {
if (this.currenthandlers.size() == 1) {
this.prevtype.visible = false;
this.nexttype.visible = false;
}
@@ -347,34 +365,11 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
this.recipeTabs.update(this);
}
private void updateRecipePage() {
final List<Integer> indices = getRecipeIndices();
final String cacheKey = indices.isEmpty() ? "empty"
: handlerInfo.getHandlerName() + ":" + indices.get(0) + ":" + indices.get(indices.size() - 1);
protected void refreshContainer() {
if (!cacheKey.equals(this.recipePageCacheKey)) {
this.recipePageCacheKey = cacheKey;
final boolean expandVertically = this.handlerInfo.expandVertically();
final List<Widget> widgets = new ArrayList<>();
int shiftY = 0;
for (int recipeIndex : indices) {
final NEIRecipeWidget widget = RecipeHandlerRef.of(this.handler.original, recipeIndex)
.getRecipeWidget();
widget.setLocation(Math.max(0, (this.container.w - widget.w) / 2), shiftY);
if (expandVertically) {
widget.h = Math.min(
this.handlerInfo.getHeight() + this.handlerInfo.getYShift(),
this.container.getVisibleHeight());
}
widgets.add(widget);
shiftY += widget.h;
}
this.container.setWidgets(widgets);
if (this.handlerPages.rebuildPages() || this.lastPage != this.handlerPages.getCurrentPageIndex()) {
this.lastPage = this.handlerPages.getCurrentPageIndex();
this.container.setWidgets(this.handlerPages.getCurrentPageWidgets());
if (this.handlerInfo.getUseCustomScroll()) {
this.container.setVerticalScroll(null);
@@ -383,10 +378,12 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
} else {
this.container.setVerticalScroll(
ScrollBar.defaultVerticalBar().setOverflowType(OverflowType.OVERLAY)
.setScrollPlace(ScrollPlace.END));
.setTrackPadding(-8, 0, 0, 0));
}
}
this.recipeCatalyst.setCatalysts(RecipeCatalysts.getRecipeCatalysts(this.handler.original));
this.container.update();
}
public static IRecipeFilter getRecipeListFilter() {
@@ -412,23 +409,20 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
return GuiRecipe.searchField.getFilter();
}
public void setRecipePage(int idx) {
setRecipePage(idx, 0);
}
public void setRecipePage(int idx, int refIndex) {
protected void setRecipePage(int idx) {
this.recipetype = (this.currenthandlers.size() + idx) % this.currenthandlers.size();
this.handler = new SearchRecipeHandler<>(this.currenthandlers.get(this.recipetype));
this.handlerInfo = GuiRecipeTab.getHandlerInfo(this.handler.original);
this.container.w = Math.max(this.xSize - 6, this.handlerInfo.getWidth());
this.handlerPages = new RecipePageManager(this.handler, this.handlerInfo, this.container);
this.prevpage.enabled = this.nextpage.enabled = this.handlerPages.getNumPages() > 1;
this.lastPage = -1;
GuiRecipe.searchField.setText("");
GuiRecipe.searchField.setVisible(false);
GuiRecipe.toggleSearch.state = 0;
this.container.setVerticalScrollOffset(0);
this.page = Math.min(Math.max(0, refIndex), this.numRecipes() - 1) / getRecipesPerPage();
changePage(0);
this.recipeTabs.update(this);
}
@@ -458,7 +452,8 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
}
}
setRecipePage(recipetype, Math.max(0, refIndex));
setRecipePage(recipetype);
this.handlerPages.gotoRefIndex(Math.max(0, refIndex));
return refIndex;
}
@@ -523,20 +518,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
}
public List<Integer> getRecipeIndices() {
final int recipesPerPage = getRecipesPerPage();
final int minIndex = this.page * recipesPerPage;
final int maxIndex = Math.min(this.numRecipes(), (this.page + 1) * recipesPerPage);
final List<Integer> range = new ArrayList<>();
for (int index = minIndex; index < maxIndex; index++) {
range.add(this.handler.ref(index));
}
return range;
}
private int numRecipes() {
return this.handler == null ? 0 : this.handler.numRecipes();
return this.handlerPages.getRecipeIndices();
}
@Override
@@ -702,11 +684,8 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
public void updateScreen() {
super.updateScreen();
this.container.w = Math.max(this.xSize - 6, this.handlerInfo.getWidth());
this.handler.original.onUpdate();
refreshPage();
this.container.update();
refreshContainer();
this.recipeCatalyst.setAvailableHeight(this.ySize - 5);
this.recipeCatalyst.y = this.guiTop;
@@ -732,7 +711,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
.contains(mousex - this.guiLeft, mousey - this.guiTop)) {
final String pageInfo = String
.format("%d/%d", page + 1, Math.max(1, this.numRecipes() - 1) / getRecipesPerPage() + 1);
.format("%d/%d", this.handlerPages.getCurrentPageIndex() + 1, this.handlerPages.getNumPages());
if (this.fontRendererObj.getStringWidth(pageInfo) >= 45) {
currenttip.add(pageInfo);
@@ -801,11 +780,11 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
}
private void nextPage() {
changePage(1);
this.handlerPages.changePage(1);
}
private void prevPage() {
changePage(-1);
this.handlerPages.changePage(-1);
}
protected void nextType() {
@@ -816,46 +795,18 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
setRecipePage(--recipetype);
}
protected void changePage(int shift) {
final int recipesPerPage = getRecipesPerPage();
final int numRecipes = this.numRecipes();
final int oldPage = this.page;
if (numRecipes > 0) {
final int numPages = (int) Math.ceil(numRecipes / (float) recipesPerPage);
this.page = Math.min(Math.max(0, this.page), numPages);
this.page = (numPages + this.page + shift) % numPages;
} else {
this.page = 0;
}
if (this.page != oldPage) {
this.container.setVerticalScrollOffset(0);
}
}
public GuiRecipeCatalyst getRecipeCatalystWidget() {
return this.recipeCatalyst;
}
public void forceRefreshPage() {
this.buttonList.removeIf(Arrays.asList(this.overlayButtons)::contains);
this.overlayButtons = new GuiOverlayButton[0];
protected void forceRefreshPage() {
this.currenthandlers.sort(NEIClientConfig.HANDLER_COMPARATOR);
this.recipePageCacheKey = "";
refreshPage();
}
public void refreshPage() {
changePage(0);
final int recipesPerPage = getRecipesPerPage();
final boolean multiplepages = this.numRecipes() > recipesPerPage;
final int currentPage = this.handlerPages.getCurrentPageIndex();
setRecipePage(this.recipetype);
this.handlerPages.changePage(currentPage);
this.prevpage.enabled = this.nextpage.enabled = multiplepages;
this.recipeCatalyst.setCatalysts(RecipeCatalysts.getRecipeCatalysts(this.handler.original));
updateRecipePage();
refreshContainer();
}
@Override
@@ -886,7 +837,6 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
}
private void drawJEITabs(int mouseX, int mouseY) {
final int recipesPerPage = getRecipesPerPage();
final int textMiddle = (BUTTON_WIDTH - this.fontRendererObj.FONT_HEIGHT) / 2;
drawRect(
@@ -920,7 +870,10 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
if (GuiRecipe.searchField.isVisible()) {
final String recipePage = NEIClientUtils.cropText(
this.fontRendererObj,
String.format("%d/%d", this.page + 1, Math.max(0, numRecipes() - 1) / recipesPerPage + 1),
String.format(
"%d/%d",
this.handlerPages.getCurrentPageIndex() + 1,
this.handlerPages.getNumPages()),
45);
drawCenteredString(
this.fontRendererObj,
@@ -929,8 +882,10 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
this.prevpage.yPosition + textMiddle,
0xffffff);
} else {
final String recipePage = NEIClientUtils
.translate("recipe.page", this.page + 1, Math.max(0, numRecipes() - 1) / recipesPerPage + 1);
final String recipePage = NEIClientUtils.translate(
"recipe.page",
this.handlerPages.getCurrentPageIndex() + 1,
this.handlerPages.getNumPages());
drawCenteredString(
this.fontRendererObj,
recipePage,
@@ -957,19 +912,6 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
return this.firstGuiGeneral;
}
private int getRecipesPerPage() {
if (this.handlerInfo.getMaxRecipesPerPage() <= 1) {
return 1;
}
if (NEIClientConfig.getBooleanSetting("inventory.guirecipe.infiniteScroll")) {
return Math.max(1, this.handler.numRecipes());
}
return Math.max(this.container.h / (this.handlerInfo.getHeight() + this.handlerInfo.getYShift()), 1);
}
public Point getRecipePosition(int recipe) {
return getRefIndexPosition(getRecipeIndices().indexOf(recipe));
}
@@ -1029,16 +971,12 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
return true;
}
if (getRecipesPerPage() == 1 && !this.container.getWidgets().isEmpty()) {
return this.container.getWidgets().get(0).bounds().intersects(rect);
}
return this.container.boundsOutside().intersects(rect);
}
protected static RecipeId getCurrentRecipeId(GuiScreen gui) {
if (gui instanceof GuiRecipe<?>gRecipe && gRecipe.handler.numRecipes() > 0) {
if (gui instanceof GuiRecipe<?>gRecipe && gRecipe.handlerPages.getNumRecipes() > 0) {
final List<Integer> indices = gRecipe.getRecipeIndices();
final int curRecipe = indices.isEmpty() ? 0 : indices.get(0);
final Recipe recipe = Recipe.of(gRecipe.handler.original, curRecipe);
@@ -60,10 +60,10 @@ public class GuiRecipeCatalyst extends ScrollContainer {
.setTextureSize(18, 18).build();
private static final ScrollBar VERTICAL_SCROLLBAR = ScrollBar.defaultVerticalBar()
.setOverflowType(ScrollBar.OverflowType.AUTO).setMarginStart(BORDER_PADDING).setMarginEnd(BORDER_PADDING)
.setPadding(-13).setScrollPlace(ScrollBar.ScrollPlace.START);
.setOverflowType(ScrollBar.OverflowType.AUTO).setTrackPadding(0, BORDER_PADDING, -13, BORDER_PADDING)
.setScrollPlace(ScrollBar.ScrollPlace.START);
private final List<PositionedStack> items = new ArrayList<>();
private PositionedStack[] items = new PositionedStack[0];
private boolean showWidget = false;
private int availableHeight = 0;
@@ -72,8 +72,7 @@ public class GuiRecipeCatalyst extends ScrollContainer {
}
public void setCatalysts(List<PositionedStack> items) {
this.items.clear();
this.items.addAll(items);
this.items = items.toArray(new PositionedStack[0]);
createWidgets();
}
@@ -95,14 +94,14 @@ public class GuiRecipeCatalyst extends ScrollContainer {
public int getColumnCount() {
if (NEIClientConfig.getJEIStyleRecipeCatalysts() == 1) {
final int maxItemsPerColumn = Math.max(0, this.availableHeight - 2 - BORDER_PADDING * 2) / SLOT_SIZE;
return maxItemsPerColumn > 0 ? NEIServerUtils.divideCeil(this.items.size(), maxItemsPerColumn) : 0;
return maxItemsPerColumn > 0 ? NEIServerUtils.divideCeil(this.items.length, maxItemsPerColumn) : 0;
}
return 1;
}
public int getRowCount() {
final int columnCount = getColumnCount();
return columnCount > 0 ? NEIServerUtils.divideCeil(this.items.size(), columnCount) : 0;
return columnCount > 0 ? NEIServerUtils.divideCeil(this.items.length, columnCount) : 0;
}
protected void createWidgets() {
@@ -118,10 +117,10 @@ public class GuiRecipeCatalyst extends ScrollContainer {
if (NEIClientConfig.getJEIStyleRecipeCatalysts() == 2
&& rows * SLOT_SIZE + this.paddingBlockStart + this.paddingBlockEnd > this.availableHeight) {
this.h = Math.min(this.h, this.availableHeight);
this.w += VERTICAL_SCROLLBAR.getScrollbarSize();
this.w += VERTICAL_SCROLLBAR.getTrackWidth();
setVerticalScroll(VERTICAL_SCROLLBAR);
setPaddingInline(BORDER_PADDING + 1 + VERTICAL_SCROLLBAR.getScrollbarSize(), this.paddingInlineEnd);
setPaddingInline(BORDER_PADDING + 1 + VERTICAL_SCROLLBAR.getTrackWidth(), this.paddingInlineEnd);
}
this.showWidget = rows * columns > 0;
@@ -255,12 +255,10 @@ public abstract class GuiRecipeTab extends Widget {
if (yShift != null && !yShift.equals("")) info.setYShift(Integer.parseInt(yShift));
try {
final int imageHeight = intOrDefault(record.get("handlerHeight"), HandlerInfo.DEFAULT_HEIGHT);
final int imageWidth = intOrDefault(record.get("handlerWidth"), HandlerInfo.DEFAULT_WIDTH);
final int maxRecipesPerPage = intOrDefault(
record.get("maxRecipesPerPage"),
HandlerInfo.DEFAULT_MAX_PER_PAGE);
info.setHandlerDimensions(imageHeight, imageWidth, maxRecipesPerPage);
final int handlerHeight = intOrDefault(record.get("handlerHeight"), HandlerInfo.DEFAULT_HEIGHT);
final int handlerWidth = intOrDefault(record.get("handlerWidth"), HandlerInfo.DEFAULT_WIDTH);
final boolean multipleWidgetsAllowed = intOrDefault(record.get("maxRecipesPerPage"), 1) > 1;
info.setHandlerDimensions(handlerWidth, handlerHeight, multipleWidgetsAllowed);
} catch (NumberFormatException ignored) {
NEIClientConfig.logger.info("Error setting handler dimensions for " + handler);
}
@@ -298,10 +296,7 @@ public abstract class GuiRecipeTab extends Widget {
private static HandlerInfo getDefaultHandlerInfo() {
final HandlerInfo info = new HandlerInfo("Unknown", "Unknown", "Unknown", false, "");
info.setHandlerDimensions(
HandlerInfo.DEFAULT_HEIGHT,
HandlerInfo.DEFAULT_WIDTH,
HandlerInfo.DEFAULT_MAX_PER_PAGE);
info.setHandlerDimensions(HandlerInfo.DEFAULT_WIDTH, HandlerInfo.DEFAULT_HEIGHT, false);
return info;
}
@@ -12,6 +12,8 @@ public class HandlerInfo {
public static int DEFAULT_HEIGHT = 65;
public static int DEFAULT_WIDTH = 166;
@Deprecated
public static int DEFAULT_MAX_PER_PAGE = 1;
private String handlerName;
@@ -24,7 +26,10 @@ public class HandlerInfo {
private int yShift = 0;
private int height = DEFAULT_HEIGHT;
private int width = DEFAULT_WIDTH;
@Deprecated
private int maxRecipesPerPage = DEFAULT_MAX_PER_PAGE;
private boolean multipleWidgetsAllowed = false;
private boolean showFavoritesButton = true;
private boolean showOverlayButton = true;
private boolean useCustomScroll = false;
@@ -40,10 +45,15 @@ public class HandlerInfo {
this.excludedModId = excludedModId;
}
@Deprecated
public void setHandlerDimensions(int height, int width, int maxRecipesPerPage) {
setHandlerDimensions(width, height, maxRecipesPerPage > 1);
}
public void setHandlerDimensions(int width, int height, boolean multipleWidgetsAllowed) {
this.height = height;
this.width = width;
this.maxRecipesPerPage = maxRecipesPerPage;
this.multipleWidgetsAllowed = multipleWidgetsAllowed;
}
public boolean setItem(String itemId, String nbtString) {
@@ -89,8 +99,13 @@ public class HandlerInfo {
return this.width;
}
@Deprecated
public int getMaxRecipesPerPage() {
return Math.max(this.maxRecipesPerPage, 1);
return this.multipleWidgetsAllowed ? Integer.MAX_VALUE : 1;
}
public boolean isMultipleWidgetsAllowed() {
return this.multipleWidgetsAllowed;
}
public int getYShift() {
@@ -133,10 +148,6 @@ public class HandlerInfo {
this.useCustomScroll = useCustomScroll;
}
public boolean expandVertically() {
return this.useCustomScroll && this.maxRecipesPerPage <= 1;
}
public static class Builder {
private final HandlerInfo info;
@@ -151,51 +162,57 @@ public class HandlerInfo {
}
public Builder setDisplayStack(ItemStack stack) {
info.image = null;
info.itemStack = stack;
this.info.image = null;
this.info.itemStack = stack;
return this;
}
public Builder setDisplayImage(DrawableResource drawable) {
info.itemStack = null;
info.image = drawable;
this.info.itemStack = null;
this.info.image = drawable;
return this;
}
public Builder setDisplayImage(ResourceLocation location, int imageX, int imageY, int imageWidth,
int imageHeight) {
info.itemStack = null;
info.setImage(location.toString(), imageX, imageY, imageWidth, imageHeight);
this.info.itemStack = null;
this.info.setImage(location.toString(), imageX, imageY, imageWidth, imageHeight);
return this;
}
public Builder setUseCustomScroll(boolean useCustomScroll) {
info.setUseCustomScroll(useCustomScroll);
this.info.setUseCustomScroll(useCustomScroll);
return this;
}
public Builder setShiftY(int shiftY) {
info.setYShift(shiftY);
this.info.setYShift(shiftY);
return this;
}
public Builder setWidth(int width) {
info.setHandlerDimensions(info.height, width, info.maxRecipesPerPage);
this.info.width = width;
return this;
}
public Builder setHeight(int height) {
info.setHandlerDimensions(height, info.width, info.maxRecipesPerPage);
this.info.height = height;
return this;
}
@Deprecated
public Builder setMaxRecipesPerPage(int maxRecipesPerPage) {
info.setHandlerDimensions(info.height, info.width, maxRecipesPerPage);
this.info.multipleWidgetsAllowed = maxRecipesPerPage > 1;
return this;
}
public Builder setMultipleWidgetsAllowed(boolean multipleWidgetsAllowed) {
this.info.multipleWidgetsAllowed = multipleWidgetsAllowed;
return this;
}
public HandlerInfo build() {
return info;
return this.info;
}
}
}
@@ -56,10 +56,10 @@ public class NEIRecipeWidget extends Widget {
}
public void update() {
this.w = Math.max(166, this.handlerInfo.getWidth());
if (this.showAsWidget || !this.handlerInfo.expandVertically()) {
if (this.showAsWidget || !this.handlerInfo.getUseCustomScroll()) {
final int recipeHeight = this.handlerRef.handler.getRecipeHeight(this.handlerRef.recipeIndex);
this.w = Math.max(166, this.handlerInfo.getWidth());
this.h = recipeHeight > 0 ? recipeHeight : this.handlerInfo.getHeight();
this.h += this.handlerInfo.getYShift();
}
@@ -0,0 +1,158 @@
package codechicken.nei.recipe;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.Widget;
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<Integer> recipeIndices = new ArrayList<>();
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;
this.pageWidgets.clear();
final boolean useCustomScroll = this.handlerInfo.getUseCustomScroll();
final int handlerHeight = this.handlerInfo.getHeight() + this.handlerInfo.getYShift();
final boolean multipleWidgetsAllowed = !useCustomScroll && handlerInfo.isMultipleWidgetsAllowed();
final boolean infiniteScroll = !useCustomScroll
&& NEIClientConfig.getBooleanSetting("inventory.guirecipe.infiniteScroll");
final int heightAvailable = this.container.getVisibleHeight();
final int width = Math.max(166, this.handlerInfo.getWidth());
final int numRecipes = getNumRecipes();
List<Widget> widgets = new ArrayList<>();
int shiftY = 0;
for (int i = 0; i < numRecipes; i++) {
final int recipeIndex = this.handler.ref(i);
final NEIRecipeWidget widget = RecipeHandlerRef.of(this.handler.original, recipeIndex).getRecipeWidget();
widget.w = width;
if (useCustomScroll) {
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() {
return !this.handlerInfo.getUseCustomScroll() && this.handlerInfo.isMultipleWidgetsAllowed();
}
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.recipeIndices = new ArrayList<>();
for (Widget widget : getCurrentPageWidgets()) {
if (widget instanceof NEIRecipeWidget recipeWidget) {
this.recipeIndices.add(recipeWidget.getRecipeHandlerRef().recipeIndex);
}
}
this.container.setVerticalScrollOffset(0);
}
public void gotoRefIndex(int refIndex) {
int page = 0;
for (int i = 0; i < this.pageWidgets.size(); i++) {
refIndex -= this.pageWidgets.get(i).size();
if (refIndex < 0) {
page = i;
break;
}
}
changePage(page);
}
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) {
if (widget instanceof NEIRecipeWidget recipeWidget) {
recipeWidget.setLocation(0, shiftY);
}
shiftY += widget.h;
}
return currentWidgets;
}
public List<Integer> getRecipeIndices() {
return this.recipeIndices;
}
}
@@ -40,12 +40,17 @@ public class ScrollBar {
private ScrollPlace scrollPlace = ScrollPlace.END;
private float handleClickOffset = -1;
private int scrollbarSize = 6;
private int thumbPadding = 0;
private int trackWidth = 6;
private int padding = 0;
private int marginStart = 0;
private int marginEnd = 0;
private int thumbPaddingLeft = 0;
private int thumbPaddingRight = 0;
private int thumbPaddingTop = 0;
private int thumbPaddingBottom = 0;
private int trackPaddingLeft = 0;
private int trackPaddingRight = 0;
private int trackPaddingTop = 0;
private int trackPaddingBottom = 0;
private DrawableResource thumbTexture;
private int thumbSliceStart;
@@ -60,58 +65,65 @@ public class ScrollBar {
}
public static ScrollBar defaultVerticalBar() {
return new ScrollBar().setScrollbarSize(8)
.setTrackTexture(new DrawableBuilder("nei:textures/nei_sprites.png", 28, 95, 11, 11).build(), 3, 4)
.setThumbTexture(new DrawableBuilder("nei:textures/nei_sprites.png", 21, 96, 7, 9).build(), 3, 2)
.setThumbPadding(1);
return new ScrollBar().setTrackWidth(8)
.setTrackTexture(new DrawableBuilder("nei:textures/nei_sprites.png", 29, 95, 8, 11).build(), 3, 4)
.setThumbTexture(new DrawableBuilder("nei:textures/nei_sprites.png", 22, 96, 6, 9).build(), 3, 2)
.setThumbPadding(1, 1, 1, 1);
}
public static ScrollBar defaultHorizontalBar() {
return new ScrollBar().setScrollbarSize(8).setOverflowType(OverflowType.SCROLL).setScrollPlace(ScrollPlace.END)
return new ScrollBar().setTrackWidth(8).setOverflowType(OverflowType.SCROLL)
.setTrackTexture(new DrawableBuilder("nei:textures/nei_sprites.png", 0, 97, 11, 8).build(), 3, 4)
.setThumbTexture(new DrawableBuilder("nei:textures/nei_sprites.png", 12, 97, 9, 7).build(), 3, 2)
.setThumbPadding(1);
.setThumbTexture(new DrawableBuilder("nei:textures/nei_sprites.png", 12, 98, 9, 6).build(), 3, 2)
.setThumbPadding(1, 1, 1, 1);
}
public ScrollBar setScrollbarSize(int scrollbarSize) {
this.scrollbarSize = scrollbarSize;
/**
* Sets the size of the scrollbar without texture in the non-scrolling axis (width for vertical, height for
* horizontal).
*
* @param trackWidth
* @return
*/
public ScrollBar setTrackWidth(int trackWidth) {
this.trackWidth = trackWidth;
return this;
}
public ScrollBar setThumbPadding(int thumbPadding) {
this.thumbPadding = thumbPadding;
public ScrollBar setTrackPadding(int left, int top, int right, int bottom) {
this.trackPaddingLeft = left;
this.trackPaddingRight = right;
this.trackPaddingTop = top;
this.trackPaddingBottom = bottom;
return this;
}
public ScrollBar setPadding(int padding) {
this.padding = padding;
public ScrollBar setThumbPadding(int left, int top, int right, int bottom) {
this.thumbPaddingLeft = left;
this.thumbPaddingRight = right;
this.thumbPaddingTop = top;
this.thumbPaddingBottom = bottom;
return this;
}
public int getPadding() {
return this.padding;
public int getTrackWidth() {
if (this.trackTexture != null) {
return this.scrollType == ScrollType.HORIZONTAL ? this.trackTexture.getHeight()
: this.trackTexture.getWidth();
}
return this.trackWidth;
}
public ScrollBar setMarginStart(int start) {
this.marginStart = start;
return this;
}
protected int getThumbWidth() {
public int getMarginStart() {
return this.marginStart;
}
if (this.thumbTexture != null) {
return this.scrollType == ScrollType.HORIZONTAL ? this.thumbTexture.getHeight()
: this.thumbTexture.getWidth();
}
public ScrollBar setMarginEnd(int end) {
this.marginEnd = end;
return this;
}
public int getMarginEnd() {
return this.marginEnd;
}
public int getScrollbarSize() {
return this.scrollbarSize;
return getTrackWidth();
}
public ScrollBar setThumbTexture(DrawableResource texture, int sliceStart, int sliceEnd) {
@@ -168,14 +180,18 @@ public class ScrollBar {
}
private int getMaxThumbSize(ScrollContainer container) {
return getMaxTrackSize(container) - this.thumbPadding * 2;
if (this.scrollType == ScrollType.HORIZONTAL) {
return getMaxTrackSize(container) - this.thumbPaddingLeft - this.thumbPaddingRight;
} else {
return getMaxTrackSize(container) - this.thumbPaddingTop - this.thumbPaddingBottom;
}
}
private int getMaxTrackSize(ScrollContainer container) {
if (this.scrollType == ScrollType.HORIZONTAL) {
return container.w - this.marginStart - this.marginEnd;
return container.w - this.trackPaddingLeft - this.trackPaddingRight;
} else {
return container.h - this.marginStart - this.marginEnd;
return container.h - this.trackPaddingTop - this.trackPaddingBottom;
}
}
@@ -212,38 +228,19 @@ public class ScrollBar {
}
public Rectangle4i trackBounds(ScrollContainer container) {
int trackWidth = getTrackWidth();
if (this.scrollType == ScrollType.HORIZONTAL) {
final int y = this.scrollPlace == ScrollPlace.START ? container.y - trackWidth - this.trackPaddingBottom
: container.y + container.h + this.trackPaddingTop;
if (this.scrollPlace == ScrollPlace.START) {
return new Rectangle4i(
container.x + this.marginStart,
container.y - this.padding - this.scrollbarSize,
getMaxTrackSize(container),
this.scrollbarSize);
} else {
return new Rectangle4i(
container.x + this.marginStart,
container.y + container.h + this.padding,
getMaxTrackSize(container),
this.scrollbarSize);
}
return new Rectangle4i(container.x + this.trackPaddingLeft, y, getMaxTrackSize(container), trackWidth);
} else {
final int x = this.scrollPlace == ScrollPlace.START ? container.x - trackWidth - this.trackPaddingRight
: container.x + container.w + this.trackPaddingLeft;
if (this.scrollPlace == ScrollPlace.START) {
return new Rectangle4i(
container.x - this.padding - this.scrollbarSize,
container.y + this.marginStart,
this.scrollbarSize,
getMaxTrackSize(container));
} else {
return new Rectangle4i(
container.x + container.w + this.padding,
container.y + this.marginStart,
this.scrollbarSize,
getMaxTrackSize(container));
}
return new Rectangle4i(x, container.y + this.trackPaddingTop, trackWidth, getMaxTrackSize(container));
}
@@ -255,9 +252,25 @@ public class ScrollBar {
final Rectangle4i bounds = trackBounds(container);
if (this.scrollType == ScrollType.HORIZONTAL) {
return new Rectangle4i(bounds.x + this.thumbPadding + offset, bounds.y, mainAxisSize, bounds.h);
final int y = this.scrollPlace == ScrollPlace.START
? bounds.y + bounds.h - getThumbWidth() - this.thumbPaddingBottom
: bounds.y + this.thumbPaddingTop;
return new Rectangle4i(
bounds.x + this.thumbPaddingLeft + offset,
y,
mainAxisSize,
bounds.h - this.thumbPaddingTop - this.thumbPaddingBottom);
} else {
return new Rectangle4i(bounds.x, bounds.y + this.thumbPadding + offset, bounds.w, mainAxisSize);
final int x = this.scrollPlace == ScrollPlace.START
? bounds.x + bounds.w - getThumbWidth() - this.thumbPaddingRight
: bounds.x + this.thumbPaddingLeft;
return new Rectangle4i(
x,
bounds.y + this.thumbPaddingTop + offset,
bounds.w - this.thumbPaddingLeft - this.thumbPaddingRight,
mainAxisSize);
}
}
@@ -278,7 +291,7 @@ public class ScrollBar {
final Rectangle4i thumbBounds = thumbBounds(container);
if (this.scrollType == ScrollType.HORIZONTAL) {
final int relativeX = mx - bounds.x - this.thumbPadding;
final int relativeX = mx - bounds.x - this.thumbPaddingLeft;
if (mx < thumbBounds.x || mx > thumbBounds.x + thumbBounds.w) {
this.handleClickOffset = mainAxisSize / 2;
@@ -290,7 +303,7 @@ public class ScrollBar {
* (container.getActualWidth() - container.getVisibleWidth())) / thumbSize;
container.setHorizontalScrollOffset((int) newOffset);
} else {
final int relativeY = my - bounds.y - this.thumbPadding;
final int relativeY = my - bounds.y - this.thumbPaddingTop;
if (my < thumbBounds.y || my > thumbBounds.y + thumbBounds.h) {
this.handleClickOffset = mainAxisSize / 2f;
@@ -318,12 +331,12 @@ public class ScrollBar {
final float thumbSize = getMaxThumbSize(container) - mainAxisSize;
if (this.scrollType == ScrollType.HORIZONTAL) {
final int relativeX = mx - bounds.x - this.thumbPadding;
final int relativeX = mx - bounds.x - this.thumbPaddingLeft;
final float newOffset = ((relativeX - this.handleClickOffset)
* (container.getActualWidth() - container.getVisibleWidth())) / thumbSize;
container.setHorizontalScrollOffset((int) newOffset);
} else {
int relativeY = my - bounds.y - this.thumbPadding;
int relativeY = my - bounds.y - this.thumbPaddingTop;
final float newOffset = ((relativeY - this.handleClickOffset)
* (container.getActualHeight() - container.getVisibleHeight())) / thumbSize;
@@ -379,7 +392,7 @@ public class ScrollBar {
}
private void drawTrackRect(ScrollContainer container, Rectangle4i bounds, float opacity) {
final float trackSize = scrollbarSize / 3f;
final float trackSize = this.trackWidth / 3f;
final Color trackColor = new Color(
BACKGROUND_COLOR.getRed(),
BACKGROUND_COLOR.getGreen(),
@@ -413,36 +426,9 @@ public class ScrollBar {
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
if (this.scrollType == ScrollType.HORIZONTAL) {
if (this.scrollPlace == ScrollPlace.START) {
texture.draw(
bounds.x,
bounds.y + (bounds.h - texture.getHeight()) / 2,
bounds.w,
texture.getHeight(),
sliceStart,
sliceEnd,
0,
0);
} else {
texture.draw(bounds.x, bounds.y, bounds.w, texture.getHeight(), sliceStart, sliceEnd, 0, 0);
}
texture.draw(bounds.x, bounds.y, bounds.w, texture.getHeight(), sliceStart, sliceEnd, 0, 0);
} else {
if (this.scrollPlace == ScrollPlace.START) {
texture.draw(
bounds.x + (bounds.w - texture.getWidth()) / 2,
bounds.y,
texture.getWidth(),
bounds.h,
0,
0,
sliceStart,
sliceEnd);
} else {
texture.draw(bounds.x, bounds.y, texture.getWidth(), bounds.h, 0, 0, sliceStart, sliceEnd);
}
texture.draw(bounds.x, bounds.y, texture.getWidth(), bounds.h, 0, 0, sliceStart, sliceEnd);
}
}