From 90720c8deee8ade3f828529c490bb4a20d653576 Mon Sep 17 00:00:00 2001 From: jchung01 <60687097+jchung01@users.noreply.github.com> Date: Sat, 9 May 2026 17:28:37 -0700 Subject: [PATCH 1/9] Skip rendering ItemStack text if empty --- .../betterquesting/api/utils/RenderUtils.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/java/betterquesting/api/utils/RenderUtils.java b/src/main/java/betterquesting/api/utils/RenderUtils.java index c11c5fadd..376dfbb78 100644 --- a/src/main/java/betterquesting/api/utils/RenderUtils.java +++ b/src/main/java/betterquesting/api/utils/RenderUtils.java @@ -22,6 +22,7 @@ import org.lwjgl.opengl.GL11; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.awt.*; import java.util.ArrayList; import java.util.List; @@ -32,19 +33,19 @@ public class RenderUtils { public static final String REGEX_NUMBER = "[^\\.0123456789-]"; // I keep screwing this up so now it's reusable - public static void RenderItemStack(Minecraft mc, ItemStack stack, int x, int y, String text) { + public static void RenderItemStack(Minecraft mc, ItemStack stack, int x, int y, @Nullable String text) { RenderItemStack(mc, stack, x, y, text, Color.WHITE.getRGB()); } - public static void RenderItemStack(Minecraft mc, ItemStack stack, int x, int y, String text, Color color) { + public static void RenderItemStack(Minecraft mc, ItemStack stack, int x, int y, @Nullable String text, Color color) { RenderItemStack(mc, stack, x, y, text, color.getRGB()); } - public static void RenderItemStack(Minecraft mc, ItemStack stack, int x, int y, String text, int color) { + public static void RenderItemStack(Minecraft mc, ItemStack stack, int x, int y, @Nullable String text, int color) { RenderItemStack(mc, stack, x, y, 16F, text, color); } - public static void RenderItemStack(Minecraft mc, ItemStack stack, int x, int y, float z, String text, int color) { + public static void RenderItemStack(Minecraft mc, ItemStack stack, int x, int y, float z, @Nullable String text, int color) { if (stack == null || stack.isEmpty()) { return; } @@ -70,7 +71,9 @@ public static void RenderItemStack(Minecraft mc, ItemStack stack, int x, int y, try { itemRender.renderItemAndEffectIntoGUI(stack, x, y); - if (stack.getCount() != 1 || text != null) { + // Custom ItemStack text + if (stack.getCount() != 1 || (text != null && !text.isEmpty())) { + String textToDraw = text == null ? String.valueOf(stack.getCount()) : text; GlStateManager.pushMatrix(); int w = getStringWidth(text, font); @@ -94,7 +97,7 @@ public static void RenderItemStack(Minecraft mc, ItemStack stack, int x, int y, GlStateManager.disableDepth(); GlStateManager.disableBlend(); - font.drawString(text, 0, 0, 16777215, true); + font.drawStringWithShadow(textToDraw, 0, 0, 16777215); GlStateManager.enableLighting(); GlStateManager.enableDepth(); @@ -103,7 +106,7 @@ public static void RenderItemStack(Minecraft mc, ItemStack stack, int x, int y, GlStateManager.popMatrix(); } - itemRender.renderItemOverlayIntoGUI(font, stack, x, y, ""); + itemRender.renderItemOverlayIntoGUI(font, stack, x, y, null); // Pass null to skip rendering default ItemStack text } catch (Exception e) { BetterQuesting.logger.warn("Unabled to render item " + stack, e); } From 45852c52cadd5e82aa9a94fc802a2f6432197224 Mon Sep 17 00:00:00 2001 From: jchung01 <60687097+jchung01@users.noreply.github.com> Date: Sat, 9 May 2026 23:21:19 -0700 Subject: [PATCH 2/9] Optimize CanvasSearch - Uncap 200 buffer limit - Enable buffering of panels for other search canvases - Reduce duplicate call to setStoredValue() when initializing item/fluid panel slots - Fix scroll position while populating search --- .../gui/controls/PanelButtonStorage.java | 5 +++ .../gui/panels/content/PanelFluidSlot.java | 4 +- .../gui/panels/content/PanelItemSlot.java | 4 +- .../panels/lists/CanvasEntityDatabase.java | 2 +- .../gui/panels/lists/CanvasFluidDatabase.java | 2 +- .../gui/panels/lists/CanvasItemDatabase.java | 2 +- .../gui/panels/lists/CanvasScrolling.java | 23 +++++----- .../panels/lists/CanvasScrollingBuffered.java | 43 ++++++++++++++++--- .../client/gui/panels/lists/CanvasSearch.java | 16 ++++--- .../gui2/editors/GuiPrerequisiteEditor.java | 6 +-- .../client/gui2/editors/GuiRewardEditor.java | 2 +- .../client/gui2/editors/GuiTaskEditor.java | 2 +- 12 files changed, 77 insertions(+), 34 deletions(-) diff --git a/src/main/java/betterquesting/api2/client/gui/controls/PanelButtonStorage.java b/src/main/java/betterquesting/api2/client/gui/controls/PanelButtonStorage.java index 5635f85d3..0a24732b7 100644 --- a/src/main/java/betterquesting/api2/client/gui/controls/PanelButtonStorage.java +++ b/src/main/java/betterquesting/api2/client/gui/controls/PanelButtonStorage.java @@ -12,6 +12,11 @@ public PanelButtonStorage(IGuiRect rect, int id, String txt, T value) { this.setStoredValue(value); } + // Overload that doesn't call setStoredValue() + protected PanelButtonStorage(IGuiRect rect, int id, String txt) { + super(rect, id, txt); + } + public PanelButtonStorage setStoredValue(T value) { this.stored = value; return this; diff --git a/src/main/java/betterquesting/api2/client/gui/panels/content/PanelFluidSlot.java b/src/main/java/betterquesting/api2/client/gui/panels/content/PanelFluidSlot.java index ee9cddf63..55b0515fa 100644 --- a/src/main/java/betterquesting/api2/client/gui/panels/content/PanelFluidSlot.java +++ b/src/main/java/betterquesting/api2/client/gui/panels/content/PanelFluidSlot.java @@ -22,11 +22,11 @@ public PanelFluidSlot(IGuiRect rect, int id, FluidStack value) { } public PanelFluidSlot(IGuiRect rect, int id, FluidStack value, boolean showCount) { - super(rect, id, "", value); + super(rect, id, ""); this.showCount = showCount; this.setTextures(PresetTexture.ITEM_FRAME.getTexture(), PresetTexture.ITEM_FRAME.getTexture(), new LayeredTexture(PresetTexture.ITEM_FRAME.getTexture(), new ColorTexture(PresetColor.ITEM_HIGHLIGHT.getColor(), new GuiPadding(1, 1, 1, 1)))); - this.setStoredValue(value); // Need to run this again because of the instatiation order of showCount + this.setStoredValue(value); // Make sure to run this because the super overload doesn't (as this depends on instantiation order of showCount) } diff --git a/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java b/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java index 1c07dabbd..7128a69bc 100644 --- a/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java +++ b/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java @@ -42,12 +42,12 @@ public PanelItemSlot(IGuiRect rect, int id, BigItemStack value, boolean showCoun } public PanelItemSlot(IGuiRect rect, int id, BigItemStack value, boolean showCount, boolean oreDict) { - super(rect, id, "", value); + super(rect, id, ""); this.showCount = showCount; this.oreDict = oreDict; this.setTextures(PresetTexture.ITEM_FRAME.getTexture(), PresetTexture.ITEM_FRAME.getTexture(), new LayeredTexture(PresetTexture.ITEM_FRAME.getTexture(), new ColorTexture(PresetColor.ITEM_HIGHLIGHT.getColor(), new GuiPadding(1, 1, 1, 1)))); - this.setStoredValue(value); // Need to run this again because of the instatiation order of showCount + this.setStoredValue(value); // Make sure to run this because the super overload doesn't (as this depends on instantiation order of showCount) } @Override diff --git a/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasEntityDatabase.java b/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasEntityDatabase.java index 46c25f033..98cb25508 100644 --- a/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasEntityDatabase.java +++ b/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasEntityDatabase.java @@ -43,7 +43,7 @@ protected boolean addResult(EntityEntry ee, int index, int cachedWidth) { return false; } - this.addPanel(new PanelButtonStorage<>(new GuiRectangle(0, index * 16, cachedWidth, 16, 0), btnId, ee.getName(), ee)); + this.addPanelToBuffer(new PanelButtonStorage<>(new GuiRectangle(0, index * 16, cachedWidth, 16, 0), btnId, ee.getName(), ee)); return true; } diff --git a/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasFluidDatabase.java b/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasFluidDatabase.java index 5ed8ab295..64599309b 100644 --- a/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasFluidDatabase.java +++ b/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasFluidDatabase.java @@ -51,7 +51,7 @@ protected boolean addResult(FluidStack stack, int index, int cachedWidth) { int x = (index % (cachedWidth / 18)) * 18; int y = (index / (cachedWidth / 18)) * 18; - this.addPanel(new PanelFluidSlot(new GuiRectangle(x, y, 18, 18, 0), btnId, stack)); + this.addPanelToBuffer(new PanelFluidSlot(new GuiRectangle(x, y, 18, 18, 0), btnId, stack)); return true; } diff --git a/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasItemDatabase.java b/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasItemDatabase.java index 24e8d933d..4443aab35 100644 --- a/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasItemDatabase.java +++ b/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasItemDatabase.java @@ -84,7 +84,7 @@ public boolean addResult(ItemStack stack, int index, int cachedWidth) { int x = (index % (cachedWidth / 18)) * 18; int y = (index / (cachedWidth / 18)) * 18; - this.addPanel(new PanelItemSlot(new GuiRectangle(x, y, 18, 18, 0), btnId, new BigItemStack(stack)).setCallback(c -> {})); + this.addPanelToBuffer(new PanelItemSlot(new GuiRectangle(x, y, 18, 18, 0), btnId, new BigItemStack(stack)).setCallback(c -> {})); return true; } diff --git a/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasScrolling.java b/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasScrolling.java index 4cb6f50db..3ee2b3356 100644 --- a/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasScrolling.java +++ b/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasScrolling.java @@ -492,17 +492,20 @@ public void refreshScrollBounds() { float zs = zoomScale.readValue(); for (IGuiPanel panel : guiPanels) { + IGuiRect transform = panel.getTransform(); + int transformX = transform.getX(); + int transformY = transform.getY(); if (first) { - left = panel.getTransform().getX(); - top = panel.getTransform().getY(); - right = panel.getTransform().getX() + panel.getTransform().getWidth(); - bottom = panel.getTransform().getY() + panel.getTransform().getHeight(); + left = transformX; + top = transformY; + right = transformX + transform.getWidth(); + bottom = transformY + transform.getHeight(); first = false; } else { - left = Math.min(left, panel.getTransform().getX()); - top = Math.min(top, panel.getTransform().getY()); - right = Math.max(right, panel.getTransform().getX() + panel.getTransform().getWidth()); - bottom = Math.max(bottom, panel.getTransform().getY() + panel.getTransform().getHeight()); + left = Math.min(left, transformX); + top = Math.min(top, transformY); + right = Math.max(right, transformX + transform.getWidth()); + bottom = Math.max(bottom, transformY + transform.getHeight()); } } @@ -511,8 +514,8 @@ public void refreshScrollBounds() { top -= margin; bottom += margin; - right -= (int) Math.ceil(this.getTransform().getWidth() / zs); - bottom -= (int) Math.ceil(this.getTransform().getHeight() / zs); + right -= (int) Math.ceil(transform.getWidth() / zs); + bottom -= (int) Math.ceil(transform.getHeight() / zs); if (extendedScroll) { scrollBounds.x = Math.min(left, right); diff --git a/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasScrollingBuffered.java b/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasScrollingBuffered.java index 21a853870..850fabd6b 100644 --- a/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasScrollingBuffered.java +++ b/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasScrollingBuffered.java @@ -1,6 +1,7 @@ package betterquesting.api2.client.gui.panels.lists; import java.util.ArrayList; +import java.util.List; import betterquesting.api2.client.gui.misc.ComparatorGuiDepth; import betterquesting.api2.client.gui.misc.IGuiRect; @@ -8,13 +9,14 @@ public class CanvasScrollingBuffered extends CanvasScrolling { - private final ArrayList buffer = new ArrayList<>(); + private final List buffer = new ArrayList<>(); + private boolean requiresSorting; public CanvasScrollingBuffered(IGuiRect rect) { super(rect); } - public void addPanelToBuffer(IGuiPanel panel) { + protected void addPanelToBuffer(IGuiPanel panel) { if (panel != null) buffer.add(panel); } @@ -22,19 +24,46 @@ public void addPanelToBuffer(IGuiPanel panel) { public void flushBuffer() { if (buffer.isEmpty()) return; - for (IGuiPanel panel : buffer) { - if (guiPanels.contains(panel)) - continue; - guiPanels.add(panel); + guiPanels.addAll(buffer); + for (IGuiPanel panel : buffer) { + if (requiresSorting || panel.getTransform().getDepth() != guiPanels.get(0).getTransform().getDepth()) { + requiresSorting = true; + } cullingManager.addPanel(panel, true); panel.initPanel(); } buffer.clear(); - guiPanels.sort(ComparatorGuiDepth.INSTANCE); + if (requiresSorting) { + guiPanels.sort(ComparatorGuiDepth.INSTANCE); + } + + this.refreshScrollBounds(); + } + + @Override + public void addCulledPanel(IGuiPanel panel, boolean useCulling) + { + if (panel == null || guiPanels.contains(panel)) return; + + guiPanels.add(panel); + if (requiresSorting || panel.getTransform().getDepth() != guiPanels.get(0).getTransform().getDepth()) { + requiresSorting = true; + guiPanels.sort(ComparatorGuiDepth.INSTANCE); + } + + cullingManager.addPanel(panel, useCulling); + + panel.initPanel(); this.refreshScrollBounds(); } + @Override + public void resetCanvas() + { + super.resetCanvas(); + requiresSorting = false; + } } diff --git a/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasSearch.java b/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasSearch.java index 0f93fd666..90e0205ac 100644 --- a/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasSearch.java +++ b/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasSearch.java @@ -1,6 +1,7 @@ package betterquesting.api2.client.gui.panels.lists; import betterquesting.api2.client.gui.misc.IGuiRect; +import betterquesting.core.BetterQuesting; import com.google.common.base.Stopwatch; import java.util.*; @@ -76,9 +77,9 @@ private void updateSearch() { searchTime.stop(); - if (!searching.hasNext()) + if (!searching.hasNext()) { searching = null; - + } } private void updateResults() { @@ -88,16 +89,21 @@ private void updateResults() { searchTime.reset().start(); - int count = 0; - while (!pendingResults.isEmpty() && searchTime.elapsed(TimeUnit.MILLISECONDS) < 10 && count < 200) { + while (!pendingResults.isEmpty() && searchTime.elapsed(TimeUnit.MILLISECONDS) < 10) { if (addResult(pendingResults.poll(), searchIdx, resultWidth)) { searchIdx++; - count++; } } searchTime.stop(); + + // Fixed scroll position + int currentScrollY = this.getScrollY(); flushBuffer(); + if (this.getScrollY() > currentScrollY) { + this.setScrollY(currentScrollY); + updatePanelScroll(); + } } public List getResults() { diff --git a/src/main/java/betterquesting/client/gui2/editors/GuiPrerequisiteEditor.java b/src/main/java/betterquesting/client/gui2/editors/GuiPrerequisiteEditor.java index be8caef25..fec4eb03f 100644 --- a/src/main/java/betterquesting/client/gui2/editors/GuiPrerequisiteEditor.java +++ b/src/main/java/betterquesting/client/gui2/editors/GuiPrerequisiteEditor.java @@ -107,14 +107,14 @@ protected boolean addResult(DBEntry entry, int index, int width) { PanelButtonStorage> btnAdd = new PanelButtonStorage<>(new GuiRectangle(0, index * 16, 16, 16, 0), 2, "", entry); btnAdd.setIcon(PresetIcon.ICON_POSITIVE.getTexture()); btnAdd.setActive(!containsReq(quest, entry.getID())); - this.addPanel(btnAdd); + this.addPanelToBuffer(btnAdd); PanelButtonStorage> btnEdit = new PanelButtonStorage<>(new GuiRectangle(16, index * 16, width - 32, 16, 0), 1, QuestTranslation.translate(entry.getValue().getProperty(NativeProps.NAME)), entry); - this.addPanel(btnEdit); + this.addPanelToBuffer(btnEdit); PanelButtonStorage> btnDel = new PanelButtonStorage<>(new GuiRectangle(width - 16, index * 16, 16, 16, 0), 4, "", entry); btnDel.setIcon(PresetIcon.ICON_TRASH.getTexture()); - this.addPanel(btnDel); + this.addPanelToBuffer(btnDel); return true; } diff --git a/src/main/java/betterquesting/client/gui2/editors/GuiRewardEditor.java b/src/main/java/betterquesting/client/gui2/editors/GuiRewardEditor.java index b78dbf2ae..45a4f986e 100644 --- a/src/main/java/betterquesting/client/gui2/editors/GuiRewardEditor.java +++ b/src/main/java/betterquesting/client/gui2/editors/GuiRewardEditor.java @@ -103,7 +103,7 @@ protected void queryMatches(IFactoryData value, String @Override protected boolean addResult(IFactoryData entry, int index, int cachedWidth) { - this.addPanel(new PanelButtonStorage<>(new GuiRectangle(0, index * 16, cachedWidth, 16, 0), 1, entry.getRegistryName().toString(), entry)); + this.addPanelToBuffer(new PanelButtonStorage<>(new GuiRectangle(0, index * 16, cachedWidth, 16, 0), 1, entry.getRegistryName().toString(), entry)); return true; } }; diff --git a/src/main/java/betterquesting/client/gui2/editors/GuiTaskEditor.java b/src/main/java/betterquesting/client/gui2/editors/GuiTaskEditor.java index 76b6686dd..8e6f49d1d 100644 --- a/src/main/java/betterquesting/client/gui2/editors/GuiTaskEditor.java +++ b/src/main/java/betterquesting/client/gui2/editors/GuiTaskEditor.java @@ -103,7 +103,7 @@ protected void queryMatches(IFactoryData value, String qu @Override protected boolean addResult(IFactoryData entry, int index, int cachedWidth) { - this.addPanel(new PanelButtonStorage<>(new GuiRectangle(0, index * 16, cachedWidth, 16, 0), 1, entry.getRegistryName().toString(), entry)); + this.addPanelToBuffer(new PanelButtonStorage<>(new GuiRectangle(0, index * 16, cachedWidth, 16, 0), 1, entry.getRegistryName().toString(), entry)); return true; } }; From a53fe3261e24485edaeb7ff62c8c4b459c423cda Mon Sep 17 00:00:00 2001 From: jchung01 <60687097+jchung01@users.noreply.github.com> Date: Sun, 10 May 2026 10:21:27 -0700 Subject: [PATCH 3/9] Remove redundant setTooltip for item slot --- .../api2/client/gui/panels/content/PanelItemSlot.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java b/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java index 7128a69bc..171d6099a 100644 --- a/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java +++ b/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java @@ -55,12 +55,9 @@ public PanelItemSlot setStoredValue(BigItemStack value) { super.setStoredValue(value); if (value != null) { - Minecraft mc = Minecraft.getMinecraft(); this.setIcon(oreDict || value.getBaseStack().getItemDamage() == OreDictionary.WILDCARD_VALUE ? new OreDictTexture(1F, value, showCount, true) : new ItemTexture(value, showCount, true), 1); - this.setTooltip(value.getBaseStack().getTooltip(mc.player, mc.gameSettings.advancedItemTooltips ? TooltipFlags.ADVANCED : TooltipFlags.NORMAL)); } else { this.setIcon(null); - this.setTooltip(null); } updateOreStacks(); From a476c51673d056846d7cf746fdddfc75d1c1bba3 Mon Sep 17 00:00:00 2001 From: jchung01 <60687097+jchung01@users.noreply.github.com> Date: Sun, 10 May 2026 12:51:49 -0700 Subject: [PATCH 4/9] Provide itemstack context to RenderTooltipEvent - Also fire RenderTooltipEvent.PostBackground --- .../betterquesting/api/utils/RenderUtils.java | 31 ++++++------------- .../api2/client/gui/GuiContainerCanvas.java | 16 ++++++++-- .../api2/client/gui/GuiScreenCanvas.java | 16 ++++++++-- .../gui/misc/IRenderedStackProvider.java | 16 ++++++++++ .../gui/panels/content/PanelItemSlot.java | 6 ++++ 5 files changed, 59 insertions(+), 26 deletions(-) create mode 100644 src/main/java/betterquesting/api2/client/gui/misc/IRenderedStackProvider.java diff --git a/src/main/java/betterquesting/api/utils/RenderUtils.java b/src/main/java/betterquesting/api/utils/RenderUtils.java index 376dfbb78..56b1c25ff 100644 --- a/src/main/java/betterquesting/api/utils/RenderUtils.java +++ b/src/main/java/betterquesting/api/utils/RenderUtils.java @@ -2,6 +2,7 @@ import betterquesting.api2.client.gui.misc.GuiRectangle; import betterquesting.api2.client.gui.misc.IGuiRect; +import betterquesting.api2.client.gui.misc.IRenderedStackProvider; import betterquesting.api2.client.gui.resources.colors.GuiColorStatic; import betterquesting.api2.client.gui.resources.colors.IGuiColor; import betterquesting.api2.client.gui.themes.presets.PresetTexture; @@ -666,6 +667,11 @@ public static void drawHoveringText(List textLines, int mouseX, int mous drawHoveringText(ItemStack.EMPTY, textLines, mouseX, mouseY, screenWidth, screenHeight, maxTextWidth, font); } + public static void drawHoveringText(IRenderedStackProvider stackProvider, List textLines, int mouseX, int mouseY, int screenWidth, int screenHeight, int maxTextWidth, FontRenderer font) { + drawHoveringText(stackProvider.getRenderedStack(), textLines, mouseX, mouseY, screenWidth, screenHeight, maxTextWidth, font); + stackProvider.resetRenderedStack(); + } + /** * Modified version of Forge's tooltip rendering that doesn't adjust Z depth */ @@ -769,29 +775,10 @@ public static void drawHoveringText(@Nonnull final ItemStack stack, List } else if (tooltipY + tooltipHeight + 4 > screenHeight) { tooltipY = screenHeight - tooltipHeight - 4; } - - /*int backgroundColor = 0xF0100010; - int borderColorStart = 0x505000FF; - int borderColorEnd = (borderColorStart & 0xFEFEFE) >> 1 | borderColorStart & 0xFF000000; - - RenderTooltipEvent.Color colorEvent = new RenderTooltipEvent.Color(stack, textLines, tooltipX, tooltipY, font, backgroundColor, borderColorStart, borderColorEnd); - MinecraftForge.EVENT_BUS.post(colorEvent); - backgroundColor = colorEvent.getBackground(); - borderColorStart = colorEvent.getBorderStart(); - borderColorEnd = colorEvent.getBorderEnd(); - - GuiUtils.drawGradientRect(0, tooltipX - 3, tooltipY - 4, tooltipX + tooltipTextWidth + 3, tooltipY - 3, backgroundColor, backgroundColor); - GuiUtils.drawGradientRect(0, tooltipX - 3, tooltipY + tooltipHeight + 3, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 4, backgroundColor, backgroundColor); - GuiUtils.drawGradientRect(0, tooltipX - 3, tooltipY - 3, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3, backgroundColor, backgroundColor); - GuiUtils.drawGradientRect(0, tooltipX - 4, tooltipY - 3, tooltipX - 3, tooltipY + tooltipHeight + 3, backgroundColor, backgroundColor); - GuiUtils.drawGradientRect(0, tooltipX + tooltipTextWidth + 3, tooltipY - 3, tooltipX + tooltipTextWidth + 4, tooltipY + tooltipHeight + 3, backgroundColor, backgroundColor); - GuiUtils.drawGradientRect(0, tooltipX - 3, tooltipY - 3 + 1, tooltipX - 3 + 1, tooltipY + tooltipHeight + 3 - 1, borderColorStart, borderColorEnd); - GuiUtils.drawGradientRect(0, tooltipX + tooltipTextWidth + 2, tooltipY - 3 + 1, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3 - 1, borderColorStart, borderColorEnd); - GuiUtils.drawGradientRect(0, tooltipX - 3, tooltipY - 3, tooltipX + tooltipTextWidth + 3, tooltipY - 3 + 1, borderColorStart, borderColorStart); - GuiUtils.drawGradientRect(0, tooltipX - 3, tooltipY + tooltipHeight + 2, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3, borderColorEnd, borderColorEnd); - - MinecraftForge.EVENT_BUS.post(new RenderTooltipEvent.PostBackground(stack, textLines, tooltipX, tooltipY, font, tooltipTextWidth, tooltipHeight));*/ + + // Doesn't fire RenderTooltipEvent.Color as we draw background/border according to theme PresetTexture.TOOLTIP_BG.getTexture().drawTexture(tooltipX - 4, tooltipY - 4, tooltipTextWidth + 8, tooltipHeight + 8, 0F, 1F); + MinecraftForge.EVENT_BUS.post(new RenderTooltipEvent.PostBackground(stack, textLines, tooltipX, tooltipY, font, tooltipTextWidth, tooltipHeight)); int tooltipTop = tooltipY; GlStateManager.translate(0F, 0F, 0.1F); diff --git a/src/main/java/betterquesting/api2/client/gui/GuiContainerCanvas.java b/src/main/java/betterquesting/api2/client/gui/GuiContainerCanvas.java index 6d6e5a673..8593e3d49 100644 --- a/src/main/java/betterquesting/api2/client/gui/GuiContainerCanvas.java +++ b/src/main/java/betterquesting/api2/client/gui/GuiContainerCanvas.java @@ -28,7 +28,7 @@ import java.util.concurrent.CopyOnWriteArrayList; // This will probably be rewritten at a later date once I reimplement Minecraft's inventory controls natively into their own isolated canvas elements -public class GuiContainerCanvas extends GuiContainer implements IScene { +public class GuiContainerCanvas extends GuiContainer implements IScene, IRenderedStackProvider { private final List guiPanels = new CopyOnWriteArrayList<>(); private final GuiRectangle rootTransform = new GuiRectangle(0, 0, 0, 0, 0); private final GuiTransform transform = new GuiTransform(GuiAlign.FULL_BOX, new GuiPadding(16, 16, 16, 16), 0); @@ -36,6 +36,7 @@ public class GuiContainerCanvas extends GuiContainer implements IScene { private boolean useMargins = true; private boolean useDefaultBG = false; private boolean isVolatile = false; + private ItemStack renderedStack = ItemStack.EMPTY; public final GuiScreen parent; @@ -396,7 +397,18 @@ protected void renderToolTip(ItemStack stack, int x, int y) { @Override protected void drawHoveringText(List textLines, int x, int y, FontRenderer font) { - RenderUtils.drawHoveringText(textLines, x, y, width, height, -1, font); + RenderUtils.drawHoveringText(this, textLines, x, y, width, height, -1, font); + } + + @Nonnull + @Override + public ItemStack getRenderedStack() { + return renderedStack; + } + + @Override + public void setRenderedStack(@Nonnull ItemStack stack) { + renderedStack = stack; } public void confirmClose(int id) { diff --git a/src/main/java/betterquesting/api2/client/gui/GuiScreenCanvas.java b/src/main/java/betterquesting/api2/client/gui/GuiScreenCanvas.java index 47cc01d74..de4b4f7b9 100644 --- a/src/main/java/betterquesting/api2/client/gui/GuiScreenCanvas.java +++ b/src/main/java/betterquesting/api2/client/gui/GuiScreenCanvas.java @@ -27,7 +27,7 @@ import java.util.ListIterator; import java.util.concurrent.CopyOnWriteArrayList; -public class GuiScreenCanvas extends GuiScreen implements IScene { +public class GuiScreenCanvas extends GuiScreen implements IScene, IRenderedStackProvider { private final List guiPanels = new CopyOnWriteArrayList<>(); private final GuiRectangle rootTransform = new GuiRectangle(0, 0, 0, 0, 0); private final GuiTransform transform = new GuiTransform(GuiAlign.FULL_BOX, new GuiPadding(16, 16, 16, 16), 0); @@ -35,6 +35,7 @@ public class GuiScreenCanvas extends GuiScreen implements IScene { private boolean useMargins = true; private boolean useDefaultBG = false; private boolean isVolatile = false; + private ItemStack renderedStack = ItemStack.EMPTY; public final GuiScreen parent; @@ -404,7 +405,18 @@ protected void renderToolTip(ItemStack stack, int x, int y) { @Override protected void drawHoveringText(List textLines, int x, int y, @Nonnull FontRenderer font) { - RenderUtils.drawHoveringText(textLines, x, y, width, height, -1, font); + RenderUtils.drawHoveringText(this, textLines, x, y, width, height, -1, font); + } + + @Nonnull + @Override + public ItemStack getRenderedStack() { + return renderedStack; + } + + @Override + public void setRenderedStack(@Nonnull ItemStack stack) { + renderedStack = stack; } private void confirmClose(int id) { diff --git a/src/main/java/betterquesting/api2/client/gui/misc/IRenderedStackProvider.java b/src/main/java/betterquesting/api2/client/gui/misc/IRenderedStackProvider.java new file mode 100644 index 000000000..7be3585d7 --- /dev/null +++ b/src/main/java/betterquesting/api2/client/gui/misc/IRenderedStackProvider.java @@ -0,0 +1,16 @@ +package betterquesting.api2.client.gui.misc; + +import javax.annotation.Nonnull; + +import net.minecraft.item.ItemStack; + +public interface IRenderedStackProvider { + @Nonnull + ItemStack getRenderedStack(); + + void setRenderedStack(@Nonnull ItemStack stack); + + default void resetRenderedStack() { + setRenderedStack(ItemStack.EMPTY); + } +} diff --git a/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java b/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java index 171d6099a..fa42f9c57 100644 --- a/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java +++ b/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java @@ -4,6 +4,7 @@ import betterquesting.api2.client.gui.controls.PanelButtonStorage; import betterquesting.api2.client.gui.misc.GuiPadding; import betterquesting.api2.client.gui.misc.IGuiRect; +import betterquesting.api2.client.gui.misc.IRenderedStackProvider; import betterquesting.api2.client.gui.resources.textures.ColorTexture; import betterquesting.api2.client.gui.resources.textures.ItemTexture; import betterquesting.api2.client.gui.resources.textures.LayeredTexture; @@ -75,6 +76,11 @@ public List getTooltip(int mx, int my) { } Minecraft mc = Minecraft.getMinecraft(); + if (mc.currentScreen instanceof IRenderedStackProvider) { + ItemStack representativeStack = ttStack.getBaseStack().copy(); + representativeStack.setCount(ttStack.stackSize); + ((IRenderedStackProvider) mc.currentScreen).setRenderedStack(representativeStack); + } return ttStack.getBaseStack().getTooltip(mc.player, mc.gameSettings.advancedItemTooltips ? TooltipFlags.ADVANCED : TooltipFlags.NORMAL); } From 19dfef42d58fe131fb805943c44bfe7163d43aaa Mon Sep 17 00:00:00 2001 From: jchung01 <60687097+jchung01@users.noreply.github.com> Date: Sun, 10 May 2026 14:29:37 -0700 Subject: [PATCH 5/9] Fix client-side leaks - Refactor bookmarking to BookmarkManager --- .../api2/client/gui/SceneController.java | 3 +- .../client/gui/controls/PanelButtonQuest.java | 7 ++-- .../client/BookmarkManager.java | 36 +++++++++++++++++++ .../betterquesting/client/gui2/GuiHome.java | 2 -- .../client/gui2/GuiQuestLines.java | 23 ++++++------ .../client/gui2/GuiQuestSearch.java | 5 +-- .../betterquesting/handlers/EventHandler.java | 7 ++-- .../betterquesting/handlers/GuiHandler.java | 7 ++-- .../handlers/SaveLoadHandler.java | 5 +-- 9 files changed, 66 insertions(+), 29 deletions(-) create mode 100644 src/main/java/betterquesting/client/BookmarkManager.java diff --git a/src/main/java/betterquesting/api2/client/gui/SceneController.java b/src/main/java/betterquesting/api2/client/gui/SceneController.java index 18006902c..c9ebe5b43 100644 --- a/src/main/java/betterquesting/api2/client/gui/SceneController.java +++ b/src/main/java/betterquesting/api2/client/gui/SceneController.java @@ -26,9 +26,10 @@ public static void setActiveScene(@Nullable IScene scene) { public static void onGuiOpened(GuiOpenEvent event) { if (event.getGui() instanceof IScene) { // TODO: Review the following - // Does this need to be cleared if the GUI isn't compatible? // Would this interfere with an overlay canvas? curScene = (IScene) event.getGui(); + } else { + curScene = null; } } } diff --git a/src/main/java/betterquesting/api2/client/gui/controls/PanelButtonQuest.java b/src/main/java/betterquesting/api2/client/gui/controls/PanelButtonQuest.java index 84914af09..eb0112d1f 100644 --- a/src/main/java/betterquesting/api2/client/gui/controls/PanelButtonQuest.java +++ b/src/main/java/betterquesting/api2/client/gui/controls/PanelButtonQuest.java @@ -33,16 +33,15 @@ public class PanelButtonQuest extends PanelButtonStorage> { public final GuiRectangle rect; - public final EntityPlayer player; public final IGuiTexture txFrame; public PanelButtonQuest(GuiRectangle rect, int id, String txt, DBEntry value) { super(rect, id, txt, value); this.rect = rect; - player = Minecraft.getMinecraft().player; + EntityPlayer player = Minecraft.getMinecraft().player; EnumQuestState qState = value == null ? EnumQuestState.LOCKED : value.getValue().getState(player); - IGuiColor txIconCol = null; + IGuiColor txIconCol; boolean lock = false; if (value != null) { @@ -67,7 +66,7 @@ public List getTooltip(int mx, int my) { if (!this.getTransform().contains(mx, my)) return null; DBEntry value = this.getStoredValue(); - return value == null ? Collections.emptyList() : getQuestTooltip(value.getValue(), player, value.getID()); + return value == null ? Collections.emptyList() : getQuestTooltip(value.getValue(), Minecraft.getMinecraft().player, value.getID()); } private List getQuestTooltip(IQuest quest, EntityPlayer player, int qID) { diff --git a/src/main/java/betterquesting/client/BookmarkManager.java b/src/main/java/betterquesting/client/BookmarkManager.java new file mode 100644 index 000000000..e61738a3e --- /dev/null +++ b/src/main/java/betterquesting/client/BookmarkManager.java @@ -0,0 +1,36 @@ +package betterquesting.client; + +import betterquesting.api2.client.gui.GuiScreenCanvas; +import betterquesting.client.gui2.GuiQuest; +import net.minecraft.client.gui.GuiScreen; + +public class BookmarkManager { + public static BookmarkManager INSTANCE = new BookmarkManager(); + + private GuiScreen parent; + private Integer questId; + + private BookmarkManager() {} + + public void setBookmark(GuiScreenCanvas parent) { + this.parent = parent; + this.questId = null; + } + + public void setBookmark(GuiScreenCanvas parent, int questId) { + this.parent = parent; + this.questId = questId; + } + + public GuiScreen getBookmark() { + if (questId == null) { + return parent; + } + return new GuiQuest(parent, questId); + } + + public void reset() { + parent = null; + questId = null; + } +} diff --git a/src/main/java/betterquesting/client/gui2/GuiHome.java b/src/main/java/betterquesting/client/gui2/GuiHome.java index d69b98b87..c73659cf9 100644 --- a/src/main/java/betterquesting/client/gui2/GuiHome.java +++ b/src/main/java/betterquesting/client/gui2/GuiHome.java @@ -52,8 +52,6 @@ @SideOnly(Side.CLIENT) public class GuiHome extends GuiScreenCanvas { - public static GuiScreen bookmark; - public GuiHome(GuiScreen parent) { super(parent); } diff --git a/src/main/java/betterquesting/client/gui2/GuiQuestLines.java b/src/main/java/betterquesting/client/gui2/GuiQuestLines.java index 4e028906d..d17af28b2 100644 --- a/src/main/java/betterquesting/client/gui2/GuiQuestLines.java +++ b/src/main/java/betterquesting/client/gui2/GuiQuestLines.java @@ -44,6 +44,7 @@ import betterquesting.api2.client.gui.themes.presets.PresetTexture; import betterquesting.api2.storage.DBEntry; import betterquesting.api2.utils.QuestTranslation; +import betterquesting.client.BookmarkManager; import betterquesting.client.gui2.editors.GuiQuestEditor; import betterquesting.client.gui2.editors.GuiQuestLinesEditor; import betterquesting.client.gui2.editors.designer.GuiDesigner; @@ -76,9 +77,9 @@ public class GuiQuestLines extends GuiScreenCanvas implements IPEventListener, I private CanvasQuestLine cvQuest; // Keep these separate for now - private static CanvasHoverTray cvChapterTray; - private static CanvasHoverTray cvDescTray; - private static CanvasHoverTray cvFrame; + private CanvasHoverTray cvChapterTray; + private CanvasHoverTray cvDescTray; + private CanvasHoverTray cvFrame; private CanvasScrolling cvDesc; private PanelVScrollBar scDesc; @@ -121,7 +122,7 @@ public void refreshGui() { public void initPanel() { super.initPanel(); - GuiHome.bookmark = this; + BookmarkManager.INSTANCE.setBookmark(this); // If we move to quest gui - we set skip home to true if (!BQ_Settings.skipHome) { ConfigHandler.config.get(Configuration.CATEGORY_GENERAL, "Skip Home", false).set(true); @@ -137,11 +138,7 @@ public void initPanel() { } boolean canEdit = QuestingAPI.getAPI(ApiReference.SETTINGS).canUserEdit(mc.player); - boolean preOpen = false; - // First time load, if tray locked - let the tray open - if (trayLock && cvChapterTray == null && cvDescTray == null) preOpen = true; - else if (trayLock && cvChapterTray != null && cvChapterTray.isTrayOpen()) preOpen = true; - else if (trayLock && cvDescTray != null && cvDescTray.isTrayOpen()) preOpen = true; + boolean preOpen = trayLock; PEventBroadcaster.INSTANCE.register(this, PEventButton.class); @@ -191,9 +188,9 @@ public void initPanel() { // === TRAY STATE === - boolean chapterTrayOpened = trayLock && cvChapterTray != null && cvChapterTray.isTrayOpen(); + boolean chapterTrayOpened = false; boolean descTrayOpened = trayLock && cvDescTray != null && cvDescTray.isTrayOpen(); - if (preOpen && !chapterTrayOpened && !descTrayOpened) { + if (preOpen && !descTrayOpened) { chapterTrayOpened = true; } @@ -461,9 +458,9 @@ private void onButtonPress(PEventButton event) { { @SuppressWarnings("unchecked") DBEntry quest = ((PanelButtonStorage>) btn).getStoredValue(); - GuiHome.bookmark = new GuiQuest(this, quest.getID()); + BookmarkManager.INSTANCE.setBookmark(this, quest.getID()); - mc.displayGuiScreen(GuiHome.bookmark); + mc.displayGuiScreen(BookmarkManager.INSTANCE.getBookmark()); } } diff --git a/src/main/java/betterquesting/client/gui2/GuiQuestSearch.java b/src/main/java/betterquesting/client/gui2/GuiQuestSearch.java index 4aa8e9ac5..75473196e 100644 --- a/src/main/java/betterquesting/client/gui2/GuiQuestSearch.java +++ b/src/main/java/betterquesting/client/gui2/GuiQuestSearch.java @@ -15,6 +15,7 @@ import betterquesting.api2.client.gui.themes.presets.PresetColor; import betterquesting.api2.client.gui.themes.presets.PresetTexture; import betterquesting.api2.utils.QuestTranslation; +import betterquesting.client.BookmarkManager; import betterquesting.misc.QuestSearchEntry; import net.minecraft.client.gui.GuiScreen; @@ -84,8 +85,8 @@ private CanvasQuestSearch createSearchCanvas() { CanvasQuestSearch canvasQuestSearch = new CanvasQuestSearch(new GuiTransform(GuiAlign.FULL_BOX, new GuiPadding(0, 32, 8, 24), 0), mc.player); canvasQuestSearch.setQuestOpenCallback(questSearchEntry -> { acceptCallback(questSearchEntry); - GuiHome.bookmark = new GuiQuest(this, questSearchEntry.getQuest().getID()); - mc.displayGuiScreen(GuiHome.bookmark); + BookmarkManager.INSTANCE.setBookmark(this, questSearchEntry.getQuest().getID()); + mc.displayGuiScreen(BookmarkManager.INSTANCE.getBookmark()); }); canvasQuestSearch.setQuestHighlightCallback(questSearchEntry -> { mc.displayGuiScreen(parent); diff --git a/src/main/java/betterquesting/handlers/EventHandler.java b/src/main/java/betterquesting/handlers/EventHandler.java index b4759dafb..f82573236 100644 --- a/src/main/java/betterquesting/handlers/EventHandler.java +++ b/src/main/java/betterquesting/handlers/EventHandler.java @@ -23,7 +23,7 @@ import betterquesting.api2.utils.ParticipantInfo; import betterquesting.api2.utils.QuestTranslation; import betterquesting.client.BQ_Keybindings; -import betterquesting.client.gui2.GuiHome; +import betterquesting.client.BookmarkManager; import betterquesting.client.gui2.GuiQuest; import betterquesting.client.gui2.GuiQuestLines; import betterquesting.client.themes.ThemeRegistry; @@ -105,8 +105,9 @@ public void onKey(InputEvent.KeyInputEvent event) { Minecraft mc = Minecraft.getMinecraft(); if (mc.currentScreen == null && BQ_Keybindings.openQuests.isPressed()) { - if (BQ_Settings.useBookmark && GuiHome.bookmark != null) { - mc.displayGuiScreen(GuiHome.bookmark); + GuiScreen bookmark = BookmarkManager.INSTANCE.getBookmark(); + if (BQ_Settings.useBookmark && bookmark != null) { + mc.displayGuiScreen(bookmark); } else { GuiScreen guiToDisplay = ThemeRegistry.INSTANCE.getGui(PresetGUIs.HOME, GArgsNone.NONE); if (BQ_Settings.useBookmark && BQ_Settings.skipHome) diff --git a/src/main/java/betterquesting/handlers/GuiHandler.java b/src/main/java/betterquesting/handlers/GuiHandler.java index a9d2a538a..82a2f0525 100644 --- a/src/main/java/betterquesting/handlers/GuiHandler.java +++ b/src/main/java/betterquesting/handlers/GuiHandler.java @@ -2,11 +2,13 @@ import betterquesting.api.storage.BQ_Settings; import betterquesting.blocks.TileSubmitStation; +import betterquesting.client.BookmarkManager; import betterquesting.client.gui2.GuiHome; import betterquesting.client.gui2.GuiQuestHelp; import betterquesting.client.gui2.editors.GuiEditLootGroup; import betterquesting.client.gui2.inventory.ContainerSubmitStation; import betterquesting.client.gui2.inventory.GuiSubmitStation; +import net.minecraft.client.gui.GuiScreen; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; @@ -37,8 +39,9 @@ public Object getClientGuiElement(int ID, EntityPlayer player, World world, int return new GuiEditLootGroup(null); } else if(ID == 3) { - if(BQ_Settings.useBookmark && GuiHome.bookmark != null) { - return GuiHome.bookmark; + GuiScreen bookmark = BookmarkManager.INSTANCE.getBookmark(); + if(BQ_Settings.useBookmark && bookmark != null) { + return bookmark; } else { return new GuiHome(null); diff --git a/src/main/java/betterquesting/handlers/SaveLoadHandler.java b/src/main/java/betterquesting/handlers/SaveLoadHandler.java index 5ab783ac5..26c5d6dff 100644 --- a/src/main/java/betterquesting/handlers/SaveLoadHandler.java +++ b/src/main/java/betterquesting/handlers/SaveLoadHandler.java @@ -8,6 +8,7 @@ import betterquesting.api.utils.JsonHelper; import betterquesting.api.utils.NBTConverter; import betterquesting.api2.utils.BQThreadedIO; +import betterquesting.client.BookmarkManager; import betterquesting.client.QuestNotification; import betterquesting.client.gui2.GuiHome; import betterquesting.commands.admin.QuestCommandDefaults; @@ -78,7 +79,7 @@ public void loadDatabases(MinecraftServer server) { hasUpdate = false; if (BetterQuesting.proxy.isClient()) { - GuiHome.bookmark = null; + BookmarkManager.INSTANCE.reset(); QuestNotification.resetNotices(); } @@ -165,7 +166,7 @@ public void unloadDatabases() { PartyManager.INSTANCE.reset(); if (BetterQuesting.proxy.isClient()) { - GuiHome.bookmark = null; + BookmarkManager.INSTANCE.reset(); QuestNotification.resetNotices(); } From dfba370ffa0a15d40f1defedbb28ddf6631da278 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+waitingidly@users.noreply.github.com> Date: Mon, 4 May 2026 12:50:10 -0700 Subject: [PATCH 6/9] Fix GuiQuestLines memory leak with correct openTray persistence # Conflicts: # src/main/java/betterquesting/client/gui2/GuiQuestLines.java --- .../client/gui2/GuiQuestLines.java | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/src/main/java/betterquesting/client/gui2/GuiQuestLines.java b/src/main/java/betterquesting/client/gui2/GuiQuestLines.java index d17af28b2..71387fdd9 100644 --- a/src/main/java/betterquesting/client/gui2/GuiQuestLines.java +++ b/src/main/java/betterquesting/client/gui2/GuiQuestLines.java @@ -67,7 +67,9 @@ public class GuiQuestLines extends GuiScreenCanvas implements IPEventListener, INeedsRefresh { - private ScrollPosition scrollPosition; + private static OpenTray openTray = OpenTray.NONE; + + private final ScrollPosition scrollPosition; private IQuestLine selectedLine = null; private static int selectedLineId = -1; @@ -76,7 +78,6 @@ public class GuiQuestLines extends GuiScreenCanvas implements IPEventListener, I private CanvasQuestLine cvQuest; - // Keep these separate for now private CanvasHoverTray cvChapterTray; private CanvasHoverTray cvDescTray; private CanvasHoverTray cvFrame; @@ -95,10 +96,8 @@ public class GuiQuestLines extends GuiScreenCanvas implements IPEventListener, I private PanelButton btnDesign; - private static boolean trayLock; - private static boolean viewMode; - private int questsCompleted = 0; - private int totalQuests = 0; + private boolean trayLock; + private boolean viewMode; private final List>> btnListRef = new ArrayList<>(); @@ -106,10 +105,7 @@ public GuiQuestLines(GuiScreen parent) { super(parent); trayLock = BQ_Settings.lockTray; viewMode = BQ_Settings.viewMode; - - if (scrollPosition == null) { - scrollPosition = new ScrollPosition(0); - } + scrollPosition = new ScrollPosition(0); } @Override @@ -138,7 +134,7 @@ public void initPanel() { } boolean canEdit = QuestingAPI.getAPI(ApiReference.SETTINGS).canUserEdit(mc.player); - boolean preOpen = trayLock; + boolean preOpen = trayLock && openTray != OpenTray.NONE; PEventBroadcaster.INSTANCE.register(this, PEventButton.class); @@ -188,11 +184,8 @@ public void initPanel() { // === TRAY STATE === - boolean chapterTrayOpened = false; - boolean descTrayOpened = trayLock && cvDescTray != null && cvDescTray.isTrayOpen(); - if (preOpen && !descTrayOpened) { - chapterTrayOpened = true; - } + boolean chapterTrayOpened = preOpen && openTray == OpenTray.CHAPTER; + boolean descTrayOpened = preOpen && openTray == OpenTray.DESCRIPTION; // === CHAPTER TRAY === @@ -244,8 +237,10 @@ public void initPanel() { PanelButton btnTrayToggle = new PanelButton(new GuiTransform(GuiAlign.TOP_LEFT, 8, 24, 32, 16, 0), -1, ""); btnTrayToggle.setIcon(PresetIcon.ICON_BOOKMARK.getTexture(), selectedLineId < 0 && !chapterTrayOpened ? new GuiColorPulse(0xFFFFFFFF, 0xFF444444, 2F, 0F) : new GuiColorStatic(0xFFFFFFFF), 0); btnTrayToggle.setClickAction((b) -> { - cvFrame.setTrayState(cvChapterTray.isTrayOpen(), 200); - cvChapterTray.setTrayState(!cvChapterTray.isTrayOpen(), 200); + boolean wasOpen = cvChapterTray.isTrayOpen(); + openTray = wasOpen ? OpenTray.NONE : OpenTray.CHAPTER; + cvFrame.setTrayState(wasOpen, 200); + cvChapterTray.setTrayState(!wasOpen, 200); btnTrayToggle.setIcon(PresetIcon.ICON_BOOKMARK.getTexture()); }); btnTrayToggle.setTooltip(Collections.singletonList(QuestTranslation.translate("betterquesting.title.quest_lines"))); @@ -253,8 +248,10 @@ public void initPanel() { PanelButton btnDescToggle = new PanelButton(new GuiTransform(GuiAlign.TOP_LEFT, 8, 40, 32, 16, 0), -1, "").setIcon(PresetIcon.ICON_DESC.getTexture()); btnDescToggle.setClickAction((b) -> { - cvFrame.setTrayState(cvDescTray.isTrayOpen(), 200); - cvDescTray.setTrayState(!cvDescTray.isTrayOpen(), 200); + boolean wasOpen = cvDescTray.isTrayOpen(); + openTray = wasOpen ? OpenTray.NONE : OpenTray.DESCRIPTION; + cvFrame.setTrayState(wasOpen, 200); + cvDescTray.setTrayState(!wasOpen, 200); }); btnDescToggle.setTooltip(Collections.singletonList(QuestTranslation.translate("betterquesting.gui.description"))); cvBackground.addPanel(btnDescToggle); @@ -581,18 +578,18 @@ private void buildChapterList() { } private void refreshQuestCompletion() { - EntityPlayer player = mc.player; - UUID playerUUId = QuestingAPI.getQuestingUUID(player); + UUID playerUUID = QuestingAPI.getQuestingUUID(mc.player); if (selectedLine == null) { return; } - questsCompleted = 0; - totalQuests = 0; + int questsCompleted = 0; + int totalQuests = 0; + var database = Objects.requireNonNull(QuestingAPI.getAPI(ApiReference.QUEST_DB)); for (DBEntry entry : selectedLine.getEntries()) { - IQuest quest = QuestingAPI.getAPI(ApiReference.QUEST_DB).getValue(entry.getID()); + IQuest quest = database.getValue(entry.getID()); if (quest.getProperty(NativeProps.LOGIC_QUEST) == EnumLogic.XOR) { // Subtract the number of requirements - 1 to simulate only doing 1 task for XOR requirements @@ -601,7 +598,7 @@ private void refreshQuestCompletion() { totalQuests++; - if (quest.isComplete(playerUUId)) { + if (quest.isComplete(playerUUID)) { questsCompleted++; } } @@ -706,6 +703,10 @@ private void highlightButton(PanelButtonQuest panelButtonQuest) { cvQuest.centerOn(panelButtonQuest); } + enum OpenTray { + NONE, CHAPTER, DESCRIPTION + } + public static class ScrollPosition{ public ScrollPosition(int chapterScrollY) { this.chapterScrollY = chapterScrollY; From ef527d59cfea4ae091730f5cbedaeac43aeeabab Mon Sep 17 00:00:00 2001 From: jchung01 <60687097+jchung01@users.noreply.github.com> Date: Mon, 11 May 2026 00:16:15 -0700 Subject: [PATCH 7/9] Address minor comments from review --- .../client/gui/panels/content/PanelItemSlot.java | 4 ++-- .../gui/panels/lists/CanvasScrollingBuffered.java | 15 ++++++++------- .../client/gui/panels/lists/CanvasSearch.java | 1 - 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java b/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java index fa42f9c57..e89a444bd 100644 --- a/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java +++ b/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java @@ -76,10 +76,10 @@ public List getTooltip(int mx, int my) { } Minecraft mc = Minecraft.getMinecraft(); - if (mc.currentScreen instanceof IRenderedStackProvider) { + if (mc.currentScreen instanceof IRenderedStackProvider renderedStackProvider) { ItemStack representativeStack = ttStack.getBaseStack().copy(); representativeStack.setCount(ttStack.stackSize); - ((IRenderedStackProvider) mc.currentScreen).setRenderedStack(representativeStack); + renderedStackProvider.setRenderedStack(representativeStack); } return ttStack.getBaseStack().getTooltip(mc.player, mc.gameSettings.advancedItemTooltips ? TooltipFlags.ADVANCED : TooltipFlags.NORMAL); } diff --git a/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasScrollingBuffered.java b/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasScrollingBuffered.java index 850fabd6b..0f58e2c9e 100644 --- a/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasScrollingBuffered.java +++ b/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasScrollingBuffered.java @@ -10,7 +10,8 @@ public class CanvasScrollingBuffered extends CanvasScrolling { private final List buffer = new ArrayList<>(); - private boolean requiresSorting; + /* If panels should be sorted by depth. Once set, should not be unset. */ + private boolean hasMultipleDepths; public CanvasScrollingBuffered(IGuiRect rect) { super(rect); @@ -26,16 +27,17 @@ public void flushBuffer() { return; guiPanels.addAll(buffer); + int depth = guiPanels.get(0).getTransform().getDepth(); for (IGuiPanel panel : buffer) { - if (requiresSorting || panel.getTransform().getDepth() != guiPanels.get(0).getTransform().getDepth()) { - requiresSorting = true; + if (hasMultipleDepths || panel.getTransform().getDepth() != depth) { + hasMultipleDepths = true; } cullingManager.addPanel(panel, true); panel.initPanel(); } buffer.clear(); - if (requiresSorting) { + if (hasMultipleDepths) { guiPanels.sort(ComparatorGuiDepth.INSTANCE); } @@ -48,8 +50,7 @@ public void addCulledPanel(IGuiPanel panel, boolean useCulling) if (panel == null || guiPanels.contains(panel)) return; guiPanels.add(panel); - if (requiresSorting || panel.getTransform().getDepth() != guiPanels.get(0).getTransform().getDepth()) { - requiresSorting = true; + if (hasMultipleDepths || panel.getTransform().getDepth() != guiPanels.get(0).getTransform().getDepth()) { guiPanels.sort(ComparatorGuiDepth.INSTANCE); } @@ -64,6 +65,6 @@ public void addCulledPanel(IGuiPanel panel, boolean useCulling) public void resetCanvas() { super.resetCanvas(); - requiresSorting = false; + hasMultipleDepths = false; } } diff --git a/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasSearch.java b/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasSearch.java index 90e0205ac..60687fb36 100644 --- a/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasSearch.java +++ b/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasSearch.java @@ -1,7 +1,6 @@ package betterquesting.api2.client.gui.panels.lists; import betterquesting.api2.client.gui.misc.IGuiRect; -import betterquesting.core.BetterQuesting; import com.google.common.base.Stopwatch; import java.util.*; From aa445d4d7380788646224e24c568e8b8380352fa Mon Sep 17 00:00:00 2001 From: jchung01 <60687097+jchung01@users.noreply.github.com> Date: Mon, 11 May 2026 01:20:35 -0700 Subject: [PATCH 8/9] Only set raw value in PanelButtonStorage with note --- .../client/gui/controls/PanelButtonStorage.java | 16 +++++++++++----- .../gui/panels/content/PanelFluidSlot.java | 4 ++-- .../client/gui/panels/content/PanelItemSlot.java | 4 ++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/main/java/betterquesting/api2/client/gui/controls/PanelButtonStorage.java b/src/main/java/betterquesting/api2/client/gui/controls/PanelButtonStorage.java index 0a24732b7..473ba743d 100644 --- a/src/main/java/betterquesting/api2/client/gui/controls/PanelButtonStorage.java +++ b/src/main/java/betterquesting/api2/client/gui/controls/PanelButtonStorage.java @@ -7,18 +7,24 @@ public class PanelButtonStorage extends PanelButton { private T stored = null; private ICallback callback = null; + /** + * Creates a panel button that stores a value. + *

+ * Note: If a subclass overrides {@link #setStoredValue(T)}, make sure to call that method during construction + * time after calling this super constructor! + *

+ */ public PanelButtonStorage(IGuiRect rect, int id, String txt, T value) { super(rect, id, txt); - this.setStoredValue(value); + setStoredRaw(value); } - // Overload that doesn't call setStoredValue() - protected PanelButtonStorage(IGuiRect rect, int id, String txt) { - super(rect, id, txt); + private void setStoredRaw(T value) { + stored = value; } public PanelButtonStorage setStoredValue(T value) { - this.stored = value; + setStoredRaw(value); return this; } diff --git a/src/main/java/betterquesting/api2/client/gui/panels/content/PanelFluidSlot.java b/src/main/java/betterquesting/api2/client/gui/panels/content/PanelFluidSlot.java index 55b0515fa..5464e5c4d 100644 --- a/src/main/java/betterquesting/api2/client/gui/panels/content/PanelFluidSlot.java +++ b/src/main/java/betterquesting/api2/client/gui/panels/content/PanelFluidSlot.java @@ -22,11 +22,11 @@ public PanelFluidSlot(IGuiRect rect, int id, FluidStack value) { } public PanelFluidSlot(IGuiRect rect, int id, FluidStack value, boolean showCount) { - super(rect, id, ""); + super(rect, id, "", null); // Value will be set by setStoredValue() this.showCount = showCount; this.setTextures(PresetTexture.ITEM_FRAME.getTexture(), PresetTexture.ITEM_FRAME.getTexture(), new LayeredTexture(PresetTexture.ITEM_FRAME.getTexture(), new ColorTexture(PresetColor.ITEM_HIGHLIGHT.getColor(), new GuiPadding(1, 1, 1, 1)))); - this.setStoredValue(value); // Make sure to run this because the super overload doesn't (as this depends on instantiation order of showCount) + this.setStoredValue(value); } diff --git a/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java b/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java index e89a444bd..fa4780098 100644 --- a/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java +++ b/src/main/java/betterquesting/api2/client/gui/panels/content/PanelItemSlot.java @@ -43,12 +43,12 @@ public PanelItemSlot(IGuiRect rect, int id, BigItemStack value, boolean showCoun } public PanelItemSlot(IGuiRect rect, int id, BigItemStack value, boolean showCount, boolean oreDict) { - super(rect, id, ""); + super(rect, id, "", null); // Value will be set by setStoredValue() this.showCount = showCount; this.oreDict = oreDict; this.setTextures(PresetTexture.ITEM_FRAME.getTexture(), PresetTexture.ITEM_FRAME.getTexture(), new LayeredTexture(PresetTexture.ITEM_FRAME.getTexture(), new ColorTexture(PresetColor.ITEM_HIGHLIGHT.getColor(), new GuiPadding(1, 1, 1, 1)))); - this.setStoredValue(value); // Make sure to run this because the super overload doesn't (as this depends on instantiation order of showCount) + this.setStoredValue(value); } @Override From ea68529845a1e51439d8fdd73f30b0841e42eded Mon Sep 17 00:00:00 2001 From: jchung01 <60687097+jchung01@users.noreply.github.com> Date: Mon, 11 May 2026 01:34:49 -0700 Subject: [PATCH 9/9] Add back set depth flag --- .../api2/client/gui/panels/lists/CanvasScrollingBuffered.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasScrollingBuffered.java b/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasScrollingBuffered.java index 0f58e2c9e..993abd082 100644 --- a/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasScrollingBuffered.java +++ b/src/main/java/betterquesting/api2/client/gui/panels/lists/CanvasScrollingBuffered.java @@ -51,6 +51,7 @@ public void addCulledPanel(IGuiPanel panel, boolean useCulling) guiPanels.add(panel); if (hasMultipleDepths || panel.getTransform().getDepth() != guiPanels.get(0).getTransform().getDepth()) { + hasMultipleDepths = true; guiPanels.sort(ComparatorGuiDepth.INSTANCE); }