From 4db4f52e4189ab1d1ec2f46706909736c1d9e374 Mon Sep 17 00:00:00 2001 From: RuiXuqi <90179819+RuiXuqi@users.noreply.github.com> Date: Wed, 12 Aug 2026 20:18:44 +0800 Subject: [PATCH 1/2] fix(mod-list): avoid repeating tab exceptions --- .../client/modlist/screen/ModListScreen.java | 46 +++++++++---------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/cleanroommc/client/modlist/screen/ModListScreen.java b/src/main/java/com/cleanroommc/client/modlist/screen/ModListScreen.java index 5f514316b..f26a31009 100644 --- a/src/main/java/com/cleanroommc/client/modlist/screen/ModListScreen.java +++ b/src/main/java/com/cleanroommc/client/modlist/screen/ModListScreen.java @@ -64,6 +64,7 @@ public class ModListScreen extends GuiScreen implements DropdownMenuHandler { private static final MutableBoolean OPTION_UPDATES_ONLY = new MutableBoolean(false); private static final MutableBoolean OPTION_FAVOURITES_ONLY = new MutableBoolean(false); private static final Map CACHED_MODS = new HashMap<>(); + private static final Set SKIPPED_TABS = new HashSet<>(); private static final TextFormatting SEARCH_FILTER_KEY = TextFormatting.GOLD; private static final TextFormatting SEARCH_FILTER_VALUE = TextFormatting.WHITE; private static final Map SEARCH_FILTERS = Map.of( @@ -605,7 +606,6 @@ private class ModListEntry implements ModListExtended.IListEntry { private final IModData data; private final ModList list; private final PinnedButton button; - private ItemStack icon; private boolean hovered; public ModListEntry(@Nonnull ModData cachedData, ModList list) { @@ -613,7 +613,7 @@ public ModListEntry(@Nonnull ModData cachedData, ModList list) { this.data = cachedData.modData; this.list = list; this.button = new PinnedButton(); - this.icon = this.getItemIcon(); + this.loadItemIcon(); } @Override @@ -672,16 +672,14 @@ private void drawIcon(int top, int left) { ModListScreen.this.itemRender.zLevel = 300.0F; try { - ModListScreen.this.itemRender.renderItemAndEffectIntoGUI(this.icon, left + 4, top + 2); + ModListScreen.this.itemRender.renderItemAndEffectIntoGUI(this.cachedData.itemIcon, left + 4, top + 2); } catch (Exception e) { // Attempt to catch exceptions when rendering item. Sometime level instance isn't checked for null ModListConstants.LOG.error("Failed to draw icon '{}' for mod '{}'. " + "To avoid issues, consider adding the mod to forceDefaultIconList", - this.icon.toString(), this.data.getModId(), e + this.cachedData.itemIcon.toString(), this.data.getModId(), e ); - ItemStack grass = new ItemStack(Blocks.GRASS); - this.cachedData.itemIcon = grass; - this.icon = grass; + this.cachedData.itemIcon = new ItemStack(Blocks.GRASS); } ModListScreen.this.zLevel = screenZ; @@ -694,19 +692,17 @@ private void drawIcon(int top, int left) { GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); } - @Nonnull - private ItemStack getItemIcon() { + private void loadItemIcon() { if (this.cachedData.itemIcon != null) { - return this.cachedData.itemIcon; + return; } // Default is grass - ItemStack defaultIcon = new ItemStack(Blocks.GRASS); - this.cachedData.itemIcon = defaultIcon; + this.cachedData.itemIcon = new ItemStack(Blocks.GRASS); for (String forcedDefaultIcon : ModListConfig.forceDefaultIconList) { if (forcedDefaultIcon.equals(this.data.getModId())) { - return defaultIcon; + return; } } @@ -719,9 +715,8 @@ private ItemStack getItemIcon() { Item item = Item.getByNameOrId(parts[0] + ":" + parts[1]); if (item != null) { int meta = parts.length > 2 ? Integer.parseInt(parts[2]) : 0; - ItemStack itemStack = new ItemStack(item, 1, meta); - this.cachedData.itemIcon = itemStack; - return itemStack; + this.cachedData.itemIcon = new ItemStack(item, 1, meta); + return; } } catch (Exception e) { ModListConstants.LOG.warn("Failed to parse item icon '{}' for mod '{}'", itemIcon, this.data.getModId(), e); @@ -730,19 +725,23 @@ private ItemStack getItemIcon() { // If the mod has a creative tab, the mod list will attempt to use the tab's icon for (CreativeTabs tab : CreativeTabs.CREATIVE_TAB_ARRAY) { - if (tab == null) continue; + if (tab == null || SKIPPED_TABS.contains(tab)) continue; ItemStack tabItem; try { tabItem = tab.getIcon(); } catch (Exception e) { - ModListConstants.LOG.warn("Failed to get creative tab icon for mod '{}'", this.data.getModId(), e); + ModListConstants.LOG.warn("Failed to get item icon for creative tab '{}'", tab.getTranslationKey(), e); + SKIPPED_TABS.add(tab); + continue; + } + if (tabItem.isEmpty()) { + SKIPPED_TABS.add(tab); continue; } - if (tabItem.isEmpty()) continue; ResourceLocation resource = tabItem.getItem().getRegistryName(); if (resource == null || !resource.getNamespace().equals(this.data.getModId())) continue; this.cachedData.itemIcon = tabItem; - return tabItem; + return; } // If the mod doesn't specify an item to use, the mod list will attempt to get an item from the mod @@ -750,12 +749,9 @@ private ItemStack getItemIcon() { if (item == null) continue; ResourceLocation resource = item.getRegistryName(); if (resource == null || !resource.getNamespace().equals(this.data.getModId())) continue; - ItemStack itemStack = new ItemStack(item); - this.cachedData.itemIcon = itemStack; - return itemStack; + this.cachedData.itemIcon = new ItemStack(item); + return; } - - return defaultIcon; } private String getFormattedModName(boolean favouriteIconVisible) { From 94f6506916e9f00350c2ce09133701b4e92d6802 Mon Sep 17 00:00:00 2001 From: RuiXuqi <90179819+RuiXuqi@users.noreply.github.com> Date: Thu, 13 Aug 2026 18:10:16 +0800 Subject: [PATCH 2/2] refactor(mod-list): impl by GuiScrollingList Impl the lists by GuiScrollingList, an old impl copied from antique MC versions. Refactor GuiScrollingList internal to align to GuiSlot while keeping compatibility with most existing extensions, but may break mixins like UT's smooth scrolling but better than crashing OptiFine whatever. --- .../client/gui/GuiListExtended.java.patch | 20 - .../minecraft/client/gui/GuiSlot.java.patch | 111 +---- .../client/modlist/screen/ModListScreen.java | 80 ++-- .../screen/widget/ModListExtended.java | 70 ++- .../screen/widget/ModListSelection.java | 3 +- .../minecraftforge/fml/client/GuiModList.java | 8 +- .../fml/client/GuiMultipleModsErrored.java | 15 +- .../fml/client/GuiScrollingList.java | 436 ++++++++++++------ .../fml/client/GuiSlotModList.java | 4 +- 9 files changed, 360 insertions(+), 387 deletions(-) delete mode 100644 patches/minecraft/net/minecraft/client/gui/GuiListExtended.java.patch diff --git a/patches/minecraft/net/minecraft/client/gui/GuiListExtended.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiListExtended.java.patch deleted file mode 100644 index 042e7bfe3..000000000 --- a/patches/minecraft/net/minecraft/client/gui/GuiListExtended.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- before/net/minecraft/client/gui/GuiListExtended.java -+++ after/net/minecraft/client/gui/GuiListExtended.java -@@ -59,7 +59,7 @@ - - if (i >= 0) - { -- int j = this.left + this.width / 2 - this.getListWidth() / 2 + 2; -+ int j = this.getListEntryLeft(); - int k = this.top + 4 - this.getAmountScrolled() + i * this.slotHeight + this.headerPadding; - int l = mouseX - j; - int i1 = mouseY - k; -@@ -79,7 +79,7 @@ - { - for (int i = 0; i < this.getSize(); i++) - { -- int j = this.left + this.width / 2 - this.getListWidth() / 2 + 2; -+ int j = this.getListEntryLeft(); - int k = this.top + 4 - this.getAmountScrolled() + i * this.slotHeight + this.headerPadding; - int l = x - j; - int i1 = y - k; diff --git a/patches/minecraft/net/minecraft/client/gui/GuiSlot.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiSlot.java.patch index b5c9df4d2..711e0af1c 100644 --- a/patches/minecraft/net/minecraft/client/gui/GuiSlot.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/GuiSlot.java.patch @@ -1,17 +1,6 @@ --- before/net/minecraft/client/gui/GuiSlot.java +++ after/net/minecraft/client/gui/GuiSlot.java -@@ -110,8 +110,8 @@ - - public int getSlotIndexFromScreenCoords(int posX, int posY) - { -- int i = this.left + this.width / 2 - this.getListWidth() / 2; -- int j = this.left + this.width / 2 + this.getListWidth() / 2; -+ int i = this.getListLeft(); -+ int j = this.getListRight(); - int k = posY - this.top - this.headerPadding + (int)this.amountScrolled - 4; - int l = k / this.slotHeight; - return posX < this.getScrollBarX() && posX >= i && posX <= j && l >= 0 && k >= 0 && l < this.getSize() ? l : -1; -@@ -186,28 +186,9 @@ +@@ -186,27 +186,8 @@ GlStateManager.disableFog(); Tessellator tessellator = Tessellator.getInstance(); BufferBuilder bufferbuilder = tessellator.getBuffer(); @@ -36,80 +25,12 @@ - .color(32, 32, 32, 255) - .endVertex(); - tessellator.draw(); -- int k = this.left + this.width / 2 - this.getListWidth() / 2 + 2; + // Forge: background rendering moved into separate method. + this.drawContainerBackground(tessellator); -+ int k = this.getListEntryLeft(); + int k = this.left + this.width / 2 - this.getListWidth() / 2 + 2; int l = this.top + 4 - (int)this.amountScrolled; - if (this.hasListHeader) -@@ -229,6 +210,7 @@ - GlStateManager.disableAlpha(); - GlStateManager.shadeModel(7425); - GlStateManager.disableTexture2D(); -+ if (this.drawTopBottomShadow(tessellator)) { - int i1 = 4; - bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); - bufferbuilder.pos(this.left, this.top + 4, 0.0).tex(0.0, 1.0).color(0, 0, 0, 0).endVertex(); -@@ -242,12 +224,12 @@ - bufferbuilder.pos(this.right, this.bottom - 4, 0.0).tex(1.0, 0.0).color(0, 0, 0, 0).endVertex(); - bufferbuilder.pos(this.left, this.bottom - 4, 0.0).tex(0.0, 0.0).color(0, 0, 0, 0).endVertex(); - tessellator.draw(); -+ } - int j1 = this.getMaxScroll(); - - if (j1 > 0) - { -- int k1 = (this.bottom - this.top) * (this.bottom - this.top) / this.getContentHeight(); -- k1 = MathHelper.clamp(k1, 32, this.bottom - this.top - 8); -+ int k1 = this.getScrollThumbHeight(); - int l1 = (int)this.amountScrolled * (this.bottom - this.top - k1) / j1 + this.top; - - if (l1 < this.top) -@@ -292,8 +274,8 @@ - && this.mouseY >= this.top - && this.mouseY <= this.bottom) - { -- int i = (this.width - this.getListWidth()) / 2; -- int j = (this.width + this.getListWidth()) / 2; -+ int i = this.getListLeft(); -+ int j = this.getListRight(); - int k = this.mouseY - this.top - this.headerPadding + (int)this.amountScrolled - 4; - int l = k / this.slotHeight; - -@@ -318,8 +300,8 @@ - - if (this.mouseY >= this.top && this.mouseY <= this.bottom) - { -- int j2 = (this.width - this.getListWidth()) / 2; -- int k2 = (this.width + this.getListWidth()) / 2; -+ int j2 = this.getListLeft(); -+ int k2 = this.getListRight(); - int l2 = this.mouseY - this.top - this.headerPadding + (int)this.amountScrolled - 4; - int i1 = l2 / this.slotHeight; - -@@ -349,8 +331,7 @@ - k1 = 1; - } - -- int l1 = (int)((float)((this.bottom - this.top) * (this.bottom - this.top)) / this.getContentHeight()); -- l1 = MathHelper.clamp(l1, 32, this.bottom - this.top - 8); -+ int l1 = this.getScrollThumbHeight(); - this.scrollMultiplier = this.scrollMultiplier / ((float)(this.bottom - this.top - l1) / k1); - } - else -@@ -429,8 +410,8 @@ - - if (this.showSelectionBox && this.isSelected(j)) - { -- int i1 = this.left + (this.width / 2 - this.getListWidth() / 2); -- int j1 = this.left + this.width / 2 + this.getListWidth() / 2; -+ int i1 = this.getListLeft(); -+ int j1 = this.getListRight(); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - GlStateManager.disableTexture2D(); - bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); -@@ -491,5 +472,57 @@ +@@ -491,5 +472,31 @@ public int getSlotHeight() { return this.slotHeight; @@ -139,31 +60,5 @@ + .color(32, 32, 32, 255) + .endVertex(); + tessellator.draw(); -+ } -+ -+ protected boolean drawTopBottomShadow(Tessellator tessellator) -+ { -+ return true; -+ } -+ -+ protected int getScrollThumbHeight() -+ { -+ int viewHeight = this.bottom - this.top; -+ return MathHelper.clamp(viewHeight * viewHeight / this.getContentHeight(), 32, viewHeight - 8); -+ } -+ -+ protected int getListLeft() -+ { -+ return this.left + this.width / 2 - this.getListWidth() / 2; -+ } -+ -+ protected int getListRight() -+ { -+ return this.left + this.width / 2 + this.getListWidth() / 2; -+ } -+ -+ protected int getListEntryLeft() -+ { -+ return this.getListLeft() + 2; } } diff --git a/src/main/java/com/cleanroommc/client/modlist/screen/ModListScreen.java b/src/main/java/com/cleanroommc/client/modlist/screen/ModListScreen.java index f26a31009..397863d48 100644 --- a/src/main/java/com/cleanroommc/client/modlist/screen/ModListScreen.java +++ b/src/main/java/com/cleanroommc/client/modlist/screen/ModListScreen.java @@ -159,7 +159,7 @@ public int getWidth() { }); this.modList = new ModList(150, ModListScreen.this.height, 46, ModListScreen.this.height - 35); - this.modList.setSlotXBoundsFromLeft(10); + this.modList.setLeft(10); this.addButton(new ModListTextButton(10, this.modList.bottom + 8, 127, 20, I18n.format("gui.back"), @@ -268,7 +268,7 @@ public void onGuiClosed() { } @Override - protected void actionPerformed(GuiButton button) throws IOException { + protected void actionPerformed(@Nonnull GuiButton button) throws IOException { if (button instanceof ModListTextButton textButton) { textButton.onClick(); return; @@ -425,7 +425,7 @@ private void drawModList(int mouseX, int mouseY, float partialTicks) { String countLabel = TextFormatting.GRAY + "(" + (totalMods + totalLibraries) + ")"; String title = modsLabel + " " + countLabel; int titleWidth = this.fontRenderer.getStringWidth(title); - int titleLeft = this.modList.left + (this.modList.width - titleWidth) / 2; + int titleLeft = this.modList.left + (this.modList.right - this.modList.left - titleWidth) / 2; this.drawString(this.fontRenderer, title, titleLeft, 10, 0xFFFFFF); int countLabelWidth = this.fontRenderer.getStringWidth(countLabel); @@ -481,7 +481,7 @@ public void drawScreen(int mouseX, int mouseY, float partialTicks) { super.drawScreen(mouseX, mouseY, partialTicks); if (this.children().isEmpty()) { String text = TextFormatting.GRAY + I18n.format("cleanroom.gui.no_mods"); - int left = this.left + this.width / 2; + int left = (this.left + this.right) / 2; int top = this.top + (this.bottom - this.top - ModListScreen.this.fontRenderer.FONT_HEIGHT) / 2; ModListScreen.this.drawCenteredString(ModListScreen.this.fontRenderer, text, left, top, 0xFFFFFFFF); } @@ -503,39 +503,24 @@ public void filterAndUpdateList() { this.clampAmountScrolled(); } - @Override - protected int getScrollBarX() { - return this.getMaxScroll() > 0 ? this.right - 6 : this.right + 1; - } - - @Override - protected int getListLeft() { - return this.left; - } - @Override protected int getListRight() { return this.getMaxScroll() > 0 ? this.right - 6 : this.right; } - @Override - protected int getListEntryLeft() { - return this.getListLeft(); - } - @Override public int getListWidth() { return this.getListRight() - this.getListLeft(); } @Override - protected void drawContainerBackground(Tessellator tessellator) { - if (this.mc.world != null) { + protected boolean drawBackground(Tessellator tessellator) { + if (this.client.world != null) { drawRect(this.left, this.top, this.right, this.bottom, 0x66000000); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - return; + return false; } - super.drawContainerBackground(tessellator); + return true; } @Override @@ -544,9 +529,9 @@ protected boolean drawTopBottomShadow(@Nullable Tessellator tessellator) { } @Override - public void handleMouseInput() { + public void handleMouseInput(int mouseX, int mouseY) throws IOException { this.hideFavourites = Mouse.getEventDWheel() != 0; - super.handleMouseInput(); + super.handleMouseInput(mouseX, mouseY); } @Override @@ -833,7 +818,7 @@ public PinnedButton() { } @Override - public void drawButton(Minecraft mc, int mouseX, int mouseY, float partialTick) { + public void drawButton(@Nonnull Minecraft mc, int mouseX, int mouseY, float partialTick) { if (!this.visible) return; this.hovered = ModListEntry.this.hovered && RenderUtils.isMouseWithin(this.x, this.y, this.width, this.height, mouseX, mouseY); this.mouseDragged(mc, mouseX, mouseY); @@ -847,7 +832,7 @@ public void drawButton(Minecraft mc, int mouseX, int mouseY, float partialTick) } @Override - public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) { + public boolean mousePressed(@Nonnull Minecraft mc, int mouseX, int mouseY) { return super.mousePressed(mc, mouseX, mouseY) && ModListEntry.this.data.getType() != IModData.Type.CHILD && !ModListEntry.this.list.shouldHideFavourites(); } } @@ -960,7 +945,7 @@ private void drawModInfo(int mouseX, int mouseY, float partialTicks) { private class StringList extends ModListExtended { public StringList(int width, int height, int left, int top) { super(ModListScreen.this.mc, width, height, top, top + height, 10); - this.setSlotXBoundsFromLeft(left + 8); + this.setLeft(left + 8); this.visible = false; } @@ -979,46 +964,47 @@ public void setTextFromInfo(@Nonnull IModData data) { } @Override - protected void drawContainerBackground(@Nullable Tessellator tessellator) { - drawRect(this.left, this.top + 1, this.left + 1, this.top + this.height - 1, 0x77000000); - drawRect(this.left + 1, this.top, this.left + this.width - 1, this.top + this.height, 0x77000000); - drawRect(this.left + this.width - 1, this.top + 1, this.left + this.width, this.top + this.height - 1, 0x77000000); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + protected int getListLeft() { + return this.left + 8; } @Override - protected boolean drawTopBottomShadow(@Nullable Tessellator tessellator) { - return false; + protected int getListRight() { + return this.right - 8; } @Override - protected int getScrollBarX() { - return this.left + this.width - 7; + protected int getListContentLeft() { + return this.getListLeft(); } @Override - protected int getListLeft() { - return this.left + 8; + public int getListWidth() { + return this.getListRight() - this.getListLeft(); } @Override - protected int getListRight() { - return this.right - 8; + protected int getScrollbarLeft() { + return this.right - 7; } @Override - protected int getListEntryLeft() { - return this.getListLeft(); + protected boolean drawBackground(@Nullable Tessellator tessellator) { + drawRect(this.left, this.top + 1, this.left + 1, this.bottom - 1, 0x77000000); + drawRect(this.left + 1, this.top, this.right - 1, this.bottom, 0x77000000); + drawRect(this.right - 1, this.top + 1, this.right, this.bottom - 1, 0x77000000); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + return false; } @Override - public int getListWidth() { - return this.getListRight() - this.getListLeft(); + protected boolean drawTopBottomShadow(@Nullable Tessellator tessellator) { + return false; } @Override public int getMaxScroll() { - return Math.max(0, this.getContentHeight() - (this.height - 12)); + return Math.max(0, this.getContentHeight() - (this.bottom - this.top - 12)); } } @@ -1222,7 +1208,7 @@ private void setSelectedModData(IModData data) { int labelCount = this.getFooterTextElementCount(data); this.descriptionList.setWidth(contentWidth); this.descriptionList.setHeight(this.height - 135 - labelCount * 15 - 9); - this.descriptionList.setSlotXBoundsFromLeft(contentLeft); + this.descriptionList.setLeft(contentLeft - 8); this.descriptionList.setTextFromInfo(data); this.descriptionList.setAmountScrolled(0); } diff --git a/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListExtended.java b/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListExtended.java index b0f6c29ff..959b54675 100644 --- a/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListExtended.java +++ b/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListExtended.java @@ -1,17 +1,16 @@ package com.cleanroommc.client.modlist.screen.widget; -import com.cleanroommc.client.modlist.RenderUtils; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiListExtended; +import net.minecraft.client.renderer.Tessellator; import net.minecraft.util.math.MathHelper; -import org.lwjgl.opengl.GL11; +import net.minecraftforge.fml.client.GuiScrollingList; import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.Collection; import java.util.List; -public class ModListExtended extends GuiListExtended { +public class ModListExtended extends GuiScrollingList { private final List entries = new ArrayList<>(); public ModListExtended(Minecraft mc, int width, int height, int top, int bottom, int slotHeight) { @@ -21,24 +20,14 @@ public ModListExtended(Minecraft mc, int width, int height, int top, int bottom, @Override public void drawScreen(int mouseX, int mouseY, float partialTicks) { if (!this.visible) return; - - RenderUtils.scissor(this.left, this.top, this.width, this.bottom - this.top); - try { - super.drawScreen(mouseX, mouseY, partialTicks); - } finally { - GL11.glDisable(GL11.GL_SCISSOR_TEST); - } - } - - @Override - protected void overlayBackground(int startY, int endY, int startAlpha, int endAlpha) { + super.drawScreen(mouseX, mouseY, partialTicks); } @Override - protected void drawSlot(int slotIndex, int x, int y, int height, int mouseX, int mouseY, float partialTicks) { - if (y + this.slotHeight >= this.top && y <= this.bottom) { - super.drawSlot(slotIndex, x, y, height, mouseX, mouseY, partialTicks); - } + protected void drawSlot(int slotIndex, int entryRight, int slotTop, int slotBuffer, Tessellator tess, float partialTicks) { + E entry = this.getListEntry(slotIndex); + entry.drawEntry(slotIndex, this.getListContentLeft(), slotTop, this.getListWidth(), slotBuffer, + this.mouseX, this.mouseY, this.getSlotIndexFromScreenCoords(this.mouseX, this.mouseY) == slotIndex, partialTicks); } @Override @@ -57,7 +46,6 @@ public final List children() { } @Nonnull - @Override public E getListEntry(int index) { return this.entries.get(index); } @@ -87,37 +75,45 @@ public void replaceEntries(Collection entries) { this.entries.addAll(entries); } - public void setAmountScrolled(float amount) { - this.amountScrolled = MathHelper.clamp(amount, 0.0F, this.getMaxScroll()); - } + public boolean mouseClicked(int mouseX, int mouseY, int mouseEvent) { + if (!this.isMouseOverList(mouseX, mouseY)) return false; + + int slotIndex = this.getSlotIndexFromScreenCoords(mouseX, mouseY); + if (slotIndex < 0) return false; - public void clampAmountScrolled() { - this.setAmountScrolled(this.amountScrolled); + E entry = this.getListEntry(slotIndex); + int relativeX = mouseX - this.getListContentLeft(); + int relativeY = mouseY - (this.top + 4 - (int) this.scrollDistance + slotIndex * this.slotHeight); + return entry.mousePressed(slotIndex, mouseX, mouseY, mouseEvent, relativeX, relativeY); } - public void setWidth(int width) { - this.width = width; - this.right = this.left + width; - this.clampAmountScrolled(); + public boolean mouseReleased(int mouseX, int mouseY, int mouseEvent) { + for (int slotIndex = 0; slotIndex < this.getSize(); slotIndex++) { + E entry = this.getListEntry(slotIndex); + int relativeX = mouseX - this.getListContentLeft(); + int relativeY = mouseY - (this.top + 4 - (int) this.scrollDistance + slotIndex * this.slotHeight); + entry.mouseReleased(slotIndex, mouseX, mouseY, mouseEvent, relativeX, relativeY); + } + return false; } - public void setHeight(int height) { - this.height = height; - this.bottom = this.top + height; - this.clampAmountScrolled(); + @Override + protected boolean shouldCenterShortContent() + { + return false; } - public interface IListEntry extends IGuiListEntry { - @Override + @SuppressWarnings("unused") + public interface IListEntry { + void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean hovered, float partialTicks); + default void updatePosition(int slotIndex, int x, int y, float partialTicks) { } - @Override default boolean mousePressed(int slotIndex, int mouseX, int mouseY, int mouseButton, int relativeX, int relativeY) { return false; } - @Override default void mouseReleased(int slotIndex, int mouseX, int mouseY, int mouseButton, int relativeX, int relativeY) { } } diff --git a/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListSelection.java b/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListSelection.java index 6736d347e..1ed155a45 100644 --- a/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListSelection.java +++ b/src/main/java/com/cleanroommc/client/modlist/screen/widget/ModListSelection.java @@ -1,11 +1,10 @@ package com.cleanroommc.client.modlist.screen.widget; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiListExtended; import javax.annotation.Nullable; -public class ModListSelection extends ModListExtended { +public class ModListSelection extends ModListExtended { private @Nullable E selected; public ModListSelection(Minecraft mc, int width, int height, int top, int bottom, int slotHeight) { diff --git a/src/main/java/net/minecraftforge/fml/client/GuiModList.java b/src/main/java/net/minecraftforge/fml/client/GuiModList.java index ce59dbb9b..78cfa9dd4 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiModList.java +++ b/src/main/java/net/minecraftforge/fml/client/GuiModList.java @@ -506,9 +506,7 @@ public Info(int width, List lines, @Nullable ResourceLocation logoPath, width, GuiModList.this.height, 32, GuiModList.this.height - 88 + 4, - GuiModList.this.listWidth + 20, 60, - GuiModList.this.width, - GuiModList.this.height); + GuiModList.this.listWidth + 20, 60); this.lines = resizeContent(lines); this.logoPath = logoPath; this.logoDims = logoDims; @@ -517,10 +515,6 @@ public Info(int width, List lines, @Nullable ResourceLocation logoPath, } @Override protected int getSize() { return 0; } - @Override protected void elementClicked(int index, boolean doubleClick) { } - @Override protected boolean isSelected(int index) { return false; } - @Override protected void drawBackground() {} - @Override protected void drawSlot(int slotIdx, int entryRight, int slotTop, int slotBuffer, Tessellator tess) { } private List resizeContent(List lines) { diff --git a/src/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java b/src/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java index a5460ea09..dd0bee409 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java +++ b/src/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java @@ -94,9 +94,7 @@ public GuiList(int entryHeight) GuiMultipleModsErrored.this.height -30, 30, GuiMultipleModsErrored.this.height-50, 10, - entryHeight, - GuiMultipleModsErrored.this.width, - GuiMultipleModsErrored.this.height); + entryHeight); } @Override @@ -105,15 +103,6 @@ protected int getSize() return 1; } - @Override - protected void elementClicked(int index, boolean doubleClick) {} - - @Override - protected boolean isSelected(int index) - { - return false; - } - @Override protected void drawBackground() { @@ -121,7 +110,7 @@ protected void drawBackground() } @Override - protected void drawSlot(int slotIdx, int entryRight, int slotTop, int slotBuffer, Tessellator tess) + protected void drawSlot(int slotIndex, int entryRight, int slotTop, int slotBuffer, Tessellator tess, float partialTicks) { int offset = slotTop; FontRenderer renderer = GuiMultipleModsErrored.this.fontRenderer; diff --git a/src/main/java/net/minecraftforge/fml/client/GuiScrollingList.java b/src/main/java/net/minecraftforge/fml/client/GuiScrollingList.java index 75d9e34b4..ee753b07a 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiScrollingList.java +++ b/src/main/java/net/minecraftforge/fml/client/GuiScrollingList.java @@ -27,24 +27,22 @@ import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraftforge.fml.client.config.GuiUtils; +import net.minecraft.util.math.MathHelper; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; import java.io.IOException; import java.util.List; -public abstract class GuiScrollingList +public abstract class GuiScrollingList extends Gui { - private final Minecraft client; + protected final Minecraft client; protected final int listWidth; protected final int listHeight; - protected final int screenWidth; - protected final int screenHeight; - protected final int top; - protected final int bottom; - protected final int right; - protected final int left; + public int top; + public int bottom; + public int right; + public int left; protected final int slotHeight; private int scrollUpActionId; private int scrollDownActionId; @@ -52,19 +50,33 @@ public abstract class GuiScrollingList protected int mouseY; private float initialMouseClickY = -2.0F; private float scrollFactor; - private float scrollDistance; + protected float scrollDistance; protected int selectedIndex = -1; private long lastClickTime = 0L; private boolean highlightSelected = true; private boolean hasHeader; private int headerHeight; + protected boolean visible = true; + // Unused + @Deprecated + protected final int screenWidth; + @Deprecated + protected final int screenHeight; + @Deprecated protected boolean captureMouse = true; - @Deprecated // We need to know screen size. + public GuiScrollingList(Minecraft client, int width, int height, int top, int bottom, int entryHeight) + { + this(client, width, height, top, bottom, 0, entryHeight); + } + public GuiScrollingList(Minecraft client, int width, int height, int top, int bottom, int left, int entryHeight) { - this(client, width, height, top, bottom, left, entryHeight, width, height); + this(client, width, height, top, bottom, left, entryHeight, getScaledWidth(client), getScaledHeight(client)); } + + @SuppressWarnings("DeprecatedIsStillUsed") + @Deprecated public GuiScrollingList(Minecraft client, int width, int height, int top, int bottom, int left, int entryHeight, int screenWidth, int screenHeight) { this.client = client; @@ -79,10 +91,18 @@ public GuiScrollingList(Minecraft client, int width, int height, int top, int bo this.screenHeight = screenHeight; } + private static int getScaledWidth(Minecraft client) { + return new ScaledResolution(client).getScaledWidth(); + } + + private static int getScaledHeight(Minecraft client) { + return new ScaledResolution(client).getScaledHeight(); + } + @Deprecated // Unused, remove in 1.9.3? - public void func_27258_a(boolean p_27258_1_) + public void func_27258_a(boolean highlightSelected) { - this.highlightSelected = p_27258_1_; + this.highlightSelected = highlightSelected; } @Deprecated protected void func_27259_a(boolean hasFooter, int footerHeight){ setHeaderInfo(hasFooter, footerHeight); } @@ -95,22 +115,28 @@ protected void setHeaderInfo(boolean hasHeader, int headerHeight) protected abstract int getSize(); - protected abstract void elementClicked(int index, boolean doubleClick); + protected void elementClicked(int index, boolean doubleClick) {} - protected abstract boolean isSelected(int index); + protected boolean isSelected(int index) { return false; } protected int getContentHeight() { return this.getSize() * this.slotHeight + this.headerHeight; } - protected abstract void drawBackground(); + protected void drawBackground() {} + + @Deprecated + protected void drawSlot(int slotIdx, int entryRight, int slotTop, int slotBuffer, Tessellator tess) {} /** * Draw anything special on the screen. GL_SCISSOR is enabled for anything that * is rendered outside of the view box. Do not mess with SCISSOR unless you support this. */ - protected abstract void drawSlot(int slotIdx, int entryRight, int slotTop, int slotBuffer, Tessellator tess); + protected void drawSlot(int slotIndex, int entryRight, int slotTop, int slotBuffer, Tessellator tess, float partialTicks) + { + drawSlot(slotIndex, entryRight, slotTop, slotBuffer, tess); + } @Deprecated protected void func_27260_a(int entryRight, int relativeY, Tessellator tess) {} /** @@ -132,11 +158,21 @@ protected int getContentHeight() @Deprecated // Unused, Remove in 1.9.3? public int func_27256_c(int x, int y) { - int left = this.left + 1; - int right = this.left + this.listWidth - 7; - int relativeY = y - this.top - this.headerHeight + (int)this.scrollDistance - 4; - int entryIndex = relativeY / this.slotHeight; - return x >= left && x <= right && entryIndex >= 0 && relativeY >= 0 && entryIndex < this.getSize() ? entryIndex : -1; + return this.getSlotIndexFromScreenCoords(x, y); + } + + public int getSlotIndexFromScreenCoords(int mouseX, int mouseY) + { + int relativeY = mouseY - this.top - this.headerHeight + (int) this.scrollDistance - 4; + int slotIndex = relativeY / this.slotHeight; + return mouseX >= this.getListLeft() && mouseX <= this.getListRight() + && (this.getMaxScroll() == 0 || mouseX < this.getScrollbarLeft()) + && slotIndex >= 0 && relativeY >= 0 && slotIndex < this.getSize() ? slotIndex : -1; + } + + public boolean isMouseOverList(int mouseX, int mouseY) + { + return mouseX >= this.left && mouseX <= this.right && mouseY >= this.top && mouseY <= this.bottom; } // FIXME: is this correct/still needed? @@ -148,11 +184,11 @@ public void registerScrollButtons(List buttons, int upActionID, int d private void applyScrollLimits() { - int listHeight = this.getContentHeight() - (this.bottom - this.top - 4); + int listHeight = this.getMaxScroll(); - if (listHeight < 0) + if (this.shouldCenterShortContent() && listHeight == 0) { - listHeight /= 2; + listHeight = (this.getContentHeight() - (this.bottom - this.top - 4)) / 2; } if (this.scrollDistance < 0.0F) @@ -160,9 +196,9 @@ private void applyScrollLimits() this.scrollDistance = 0.0F; } - if (this.scrollDistance > (float)listHeight) + if (this.scrollDistance > listHeight) { - this.scrollDistance = (float)listHeight; + this.scrollDistance = listHeight; } } @@ -185,96 +221,104 @@ else if (button.id == this.scrollDownActionId) } } + public void handleMouseInput() throws IOException + { + this.handleMouseInput(this.mouseX, this.mouseY); + } public void handleMouseInput(int mouseX, int mouseY) throws IOException { - boolean isHovering = mouseX >= this.left && mouseX <= this.left + this.listWidth && - mouseY >= this.top && mouseY <= this.bottom; - if (!isHovering) - return; + int mouseButton = Mouse.getEventButton(); + boolean mouseButtonState = Mouse.getEventButtonState(); + boolean isHovering = this.isMouseOverList(mouseX, mouseY); - int scroll = Mouse.getEventDWheel(); - if (scroll != 0) + if (!this.visible) { - this.scrollDistance += (float)((-1 * scroll) * this.slotHeight / 2); + if (mouseButton == 0 && !mouseButtonState) + { + this.initialMouseClickY = -1.0F; + } + return; } - } - - public void drawScreen(int mouseX, int mouseY, float partialTicks) - { - this.mouseX = mouseX; - this.mouseY = mouseY; - this.drawBackground(); - boolean isHovering = mouseX >= this.left && mouseX <= this.left + this.listWidth && - mouseY >= this.top && mouseY <= this.bottom; - int listLength = this.getSize(); - int scrollBarWidth = 6; - int scrollBarRight = this.left + this.listWidth; - int scrollBarLeft = scrollBarRight - scrollBarWidth; - int entryLeft = this.left; - int entryRight = scrollBarLeft - 1; - int viewHeight = this.bottom - this.top; - int border = 4; + if (isHovering) + { + int scroll = Mouse.getEventDWheel(); + if (scroll != 0) + { + this.scrollDistance += (float)((-1 * scroll) * this.slotHeight / 2); + } + } - if (Mouse.isButtonDown(0)) + if (mouseButton == 0 && mouseButtonState && isHovering) { - if (this.initialMouseClickY == -1.0F) + int listLength = this.getSize(); + int scrollBarLeft = this.getScrollbarLeft(); + int scrollBarRight = scrollBarLeft + 6; + int entryLeft = this.getListLeft(); + int entryRight = this.getListRight(); + int viewHeight = this.bottom - this.top; + int border = 4; + int mouseListY = mouseY - this.top - this.headerHeight + (int)this.scrollDistance - border; + int slotIndex = mouseListY / this.slotHeight; + + if (mouseX >= entryLeft && mouseX <= entryRight && slotIndex >= 0 && mouseListY >= 0 && slotIndex < listLength) { - if (isHovering) - { - int mouseListY = mouseY - this.top - this.headerHeight + (int)this.scrollDistance - border; - int slotIndex = mouseListY / this.slotHeight; - - if (mouseX >= entryLeft && mouseX <= entryRight && slotIndex >= 0 && mouseListY >= 0 && slotIndex < listLength) - { - this.elementClicked(slotIndex, slotIndex == this.selectedIndex && System.currentTimeMillis() - this.lastClickTime < 250L); - this.selectedIndex = slotIndex; - this.lastClickTime = System.currentTimeMillis(); - } - else if (mouseX >= entryLeft && mouseX <= entryRight && mouseListY < 0) - { - this.clickHeader(mouseX - entryLeft, mouseY - this.top + (int)this.scrollDistance - border); - } - - if (mouseX >= scrollBarLeft && mouseX <= scrollBarRight) - { - this.scrollFactor = -1.0F; - int scrollHeight = this.getContentHeight() - viewHeight - border; - if (scrollHeight < 1) scrollHeight = 1; - - int var13 = (int)((float)(viewHeight * viewHeight) / (float)this.getContentHeight()); - - if (var13 < 32) var13 = 32; - if (var13 > viewHeight - border*2) - var13 = viewHeight - border*2; - - this.scrollFactor /= (float)(viewHeight - var13) / (float)scrollHeight; - } - else - { - this.scrollFactor = 1.0F; - } - - this.initialMouseClickY = mouseY; - } - else + this.elementClicked(slotIndex, slotIndex == this.selectedIndex && System.currentTimeMillis() - this.lastClickTime < 250L); + this.selectedIndex = slotIndex; + this.lastClickTime = System.currentTimeMillis(); + } + else if (mouseX >= entryLeft && mouseX <= entryRight && mouseListY < 0) + { + this.clickHeader(mouseX - entryLeft, mouseY - this.top + (int)this.scrollDistance - border); + } + + if (mouseX >= scrollBarLeft && mouseX <= scrollBarRight) + { + this.scrollFactor = -1.0F; + int scrollHeight = this.getContentHeight() - viewHeight - border; + if (scrollHeight < 1) scrollHeight = 1; + + int thumbHeight = this.getScrollThumbHeight(); + if (viewHeight > thumbHeight) { - this.initialMouseClickY = -2.0F; + this.scrollFactor /= (float) (viewHeight - thumbHeight) / scrollHeight; } } - else if (this.initialMouseClickY >= 0.0F) + else { - this.scrollDistance -= ((float)mouseY - this.initialMouseClickY) * this.scrollFactor; - this.initialMouseClickY = (float)mouseY; + this.scrollFactor = 1.0F; } + + this.initialMouseClickY = mouseY; + } + else if (mouseButton == -1 && this.initialMouseClickY >= 0.0F) + { + this.scrollDistance -= (mouseY - this.initialMouseClickY) * this.scrollFactor; + this.initialMouseClickY = mouseY; } - else + else if (mouseButton == 0 && !mouseButtonState) { this.initialMouseClickY = -1.0F; } this.applyScrollLimits(); + } + + public void drawScreen(int mouseX, int mouseY, float partialTicks) + { + this.mouseX = mouseX; + this.mouseY = mouseY; + this.drawBackground(); + + int listLength = this.getSize(); + int scrollBarWidth = 6; + int scrollBarLeft = this.getScrollbarLeft(); + int scrollBarRight = scrollBarLeft + scrollBarWidth; + int entryLeft = this.getListLeft(); + int entryRight = this.getListRight(); + int viewHeight = this.bottom - this.top; + int border = 4; Tessellator tess = Tessellator.getInstance(); BufferBuilder worldr = tess.getBuffer(); @@ -283,26 +327,30 @@ else if (this.initialMouseClickY >= 0.0F) double scaleW = client.displayWidth / res.getScaledWidth_double(); double scaleH = client.displayHeight / res.getScaledHeight_double(); GL11.glEnable(GL11.GL_SCISSOR_TEST); - GL11.glScissor((int)(left * scaleW), (int)(client.displayHeight - (bottom * scaleH)), - (int)(listWidth * scaleW), (int)(viewHeight * scaleH)); + GL11.glScissor((int)(left * scaleW), (int)(client.displayHeight - (bottom * scaleH)), + (int)((right - left) * scaleW), (int)(viewHeight * scaleH)); - if (this.client.world != null) - { - this.drawGradientRect(this.left, this.top, this.right, this.bottom, 0xC0101010, 0xD0101010); - } - else // Draw dark dirt background + if (this.drawBackground(tess)) { - GlStateManager.disableLighting(); - GlStateManager.disableFog(); - this.client.renderEngine.bindTexture(Gui.OPTIONS_BACKGROUND); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - final float scale = 32.0F; - worldr.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); - worldr.pos(this.left, this.bottom, 0.0D).tex(this.left / scale, (this.bottom + (int)this.scrollDistance) / scale).color(0x20, 0x20, 0x20, 0xFF).endVertex(); - worldr.pos(this.right, this.bottom, 0.0D).tex(this.right / scale, (this.bottom + (int)this.scrollDistance) / scale).color(0x20, 0x20, 0x20, 0xFF).endVertex(); - worldr.pos(this.right, this.top, 0.0D).tex(this.right / scale, (this.top + (int)this.scrollDistance) / scale).color(0x20, 0x20, 0x20, 0xFF).endVertex(); - worldr.pos(this.left, this.top, 0.0D).tex(this.left / scale, (this.top + (int)this.scrollDistance) / scale).color(0x20, 0x20, 0x20, 0xFF).endVertex(); - tess.draw(); + if (this.client.world != null) + { + this.drawGradientRect(this.left, this.top, this.right, this.bottom, 0xC0101010, 0xD0101010); + } + else // Draw dark dirt background + { + GlStateManager.disableLighting(); + GlStateManager.disableFog(); + this.client.getTextureManager().bindTexture(OPTIONS_BACKGROUND); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + float scale = 32.0F; + BufferBuilder buffer = tess.getBuffer(); + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); + buffer.pos(this.left, this.bottom, 0.0D).tex(this.left / scale, (this.bottom + (int) this.scrollDistance) / scale).color(0x20, 0x20, 0x20, 0xFF).endVertex(); + buffer.pos(this.right, this.bottom, 0.0D).tex(this.right / scale, (this.bottom + (int) this.scrollDistance) / scale).color(0x20, 0x20, 0x20, 0xFF).endVertex(); + buffer.pos(this.right, this.top, 0.0D).tex(this.right / scale, (this.top + (int) this.scrollDistance) / scale).color(0x20, 0x20, 0x20, 0xFF).endVertex(); + buffer.pos(this.left, this.top, 0.0D).tex(this.left / scale, (this.top + (int) this.scrollDistance) / scale).color(0x20, 0x20, 0x20, 0xFF).endVertex(); + tess.draw(); + } } int baseY = this.top + border - (int)this.scrollDistance; @@ -320,8 +368,8 @@ else if (this.initialMouseClickY >= 0.0F) { if (this.highlightSelected && this.isSelected(slotIdx)) { - int min = this.left; - int max = entryRight; + int min = this.getListLeft(); + int max = this.getListRight(); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); GlStateManager.disableTexture2D(); worldr.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); @@ -337,41 +385,39 @@ else if (this.initialMouseClickY >= 0.0F) GlStateManager.enableTexture2D(); } - this.drawSlot(slotIdx, entryRight, slotTop, slotBuffer, tess); + this.drawSlot(slotIdx, entryRight, slotTop, slotBuffer, tess, partialTicks); } } - GlStateManager.disableTexture2D(); - GlStateManager.enableBlend(); - GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ZERO, GlStateManager.DestFactor.ONE); - GlStateManager.shadeModel(GL11.GL_SMOOTH); - worldr.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); - worldr.pos((double)this.left, (double)(this.top + 4), 0.0D).tex(0.0D, 1.0D).color(0, 0, 0, 0).endVertex(); - worldr.pos((double)this.right, (double)(this.top + 4), 0.0D).tex(1.0D, 1.0D).color(0, 0, 0, 0).endVertex(); - worldr.pos((double)this.right, (double)this.top, 0.0D).tex(1.0D, 0.0D).color(0, 0, 0, 255).endVertex(); - worldr.pos((double)this.left, (double)this.top, 0.0D).tex(0.0D, 0.0D).color(0, 0, 0, 255).endVertex(); - tess.draw(); - worldr.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); - worldr.pos((double)this.left, (double)this.bottom, 0.0D).tex(0.0D, 1.0D).color(0, 0, 0, 255).endVertex(); - worldr.pos((double)this.right, (double)this.bottom, 0.0D).tex(1.0D, 1.0D).color(0, 0, 0, 255).endVertex(); - worldr.pos((double)this.right, (double)(this.bottom - 4), 0.0D).tex(1.0D, 0.0D).color(0, 0, 0, 0).endVertex(); - worldr.pos((double)this.left, (double)(this.bottom - 4), 0.0D).tex(0.0D, 0.0D).color(0, 0, 0, 0).endVertex(); - tess.draw(); - GlStateManager.shadeModel(GL11.GL_FLAT); - GlStateManager.disableBlend(); - GlStateManager.enableTexture2D(); - + if (this.drawTopBottomShadow(tess)) + { + GlStateManager.disableTexture2D(); + GlStateManager.enableBlend(); + GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ZERO, GlStateManager.DestFactor.ONE); + GlStateManager.shadeModel(GL11.GL_SMOOTH); + BufferBuilder buffer = tess.getBuffer(); + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); + buffer.pos(this.left, this.top + 4, 0).tex(0, 1).color(0x00, 0x00, 0x00, 0x00).endVertex(); + buffer.pos(this.right, this.top + 4, 0).tex(1, 1).color(0x00, 0x00, 0x00, 0x00).endVertex(); + buffer.pos(this.right, this.top, 0).tex(1, 0).color(0x00, 0x00, 0x00, 0xFF).endVertex(); + buffer.pos(this.left, this.top, 0).tex(0, 0).color(0x00, 0x00, 0x00, 0xFF).endVertex(); + tess.draw(); + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); + buffer.pos(this.left, this.bottom, 0).tex(0, 1).color(0x00, 0x00, 0x00, 0xFF).endVertex(); + buffer.pos(this.right, this.bottom, 0).tex(1, 1).color(0x00, 0x00, 0x00, 0xFF).endVertex(); + buffer.pos(this.right, this.bottom - 4, 0).tex(1, 0).color(0x00, 0x00, 0x00, 0x00).endVertex(); + buffer.pos(this.left, this.bottom - 4, 0).tex(0, 0).color(0x00, 0x00, 0x00, 0x00).endVertex(); + tess.draw(); + GlStateManager.shadeModel(GL11.GL_FLAT); + GlStateManager.disableBlend(); + GlStateManager.enableTexture2D(); + } GlStateManager.disableDepth(); int extraHeight = (this.getContentHeight() + border) - viewHeight; if (extraHeight > 0) { - int height = (viewHeight * viewHeight) / this.getContentHeight(); - - if (height < 32) height = 32; - - if (height > viewHeight - border*2) - height = viewHeight - border*2; + int height = this.getScrollThumbHeight(); int barTop = (int)this.scrollDistance * (viewHeight - height) / extraHeight + this.top; if (barTop < this.top) @@ -389,14 +435,14 @@ else if (this.initialMouseClickY >= 0.0F) worldr.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); worldr.pos(scrollBarLeft, barTop + height, 0.0D).tex(0.0D, 1.0D).color(0x80, 0x80, 0x80, 0xFF).endVertex(); worldr.pos(scrollBarRight, barTop + height, 0.0D).tex(1.0D, 1.0D).color(0x80, 0x80, 0x80, 0xFF).endVertex(); - worldr.pos(scrollBarRight, barTop, 0.0D).tex(1.0D, 0.0D).color(0x80, 0x80, 0x80, 0xFF).endVertex(); - worldr.pos(scrollBarLeft, barTop, 0.0D).tex(0.0D, 0.0D).color(0x80, 0x80, 0x80, 0xFF).endVertex(); + worldr.pos(scrollBarRight, barTop, 0.0D).tex(1.0D, 0.0D).color(0x80, 0x80, 0x80, 0xFF).endVertex(); + worldr.pos(scrollBarLeft, barTop, 0.0D).tex(0.0D, 0.0D).color(0x80, 0x80, 0x80, 0xFF).endVertex(); tess.draw(); worldr.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); - worldr.pos(scrollBarLeft, barTop + height - 1, 0.0D).tex(0.0D, 1.0D).color(0xC0, 0xC0, 0xC0, 0xFF).endVertex(); + worldr.pos(scrollBarLeft, barTop + height - 1, 0.0D).tex(0.0D, 1.0D).color(0xC0, 0xC0, 0xC0, 0xFF).endVertex(); worldr.pos(scrollBarRight - 1, barTop + height - 1, 0.0D).tex(1.0D, 1.0D).color(0xC0, 0xC0, 0xC0, 0xFF).endVertex(); - worldr.pos(scrollBarRight - 1, barTop, 0.0D).tex(1.0D, 0.0D).color(0xC0, 0xC0, 0xC0, 0xFF).endVertex(); - worldr.pos(scrollBarLeft, barTop, 0.0D).tex(0.0D, 0.0D).color(0xC0, 0xC0, 0xC0, 0xFF).endVertex(); + worldr.pos(scrollBarRight - 1, barTop, 0.0D).tex(1.0D, 0.0D).color(0xC0, 0xC0, 0xC0, 0xFF).endVertex(); + worldr.pos(scrollBarLeft, barTop, 0.0D).tex(0.0D, 0.0D).color(0xC0, 0xC0, 0xC0, 0xFF).endVertex(); tess.draw(); } @@ -408,8 +454,96 @@ else if (this.initialMouseClickY >= 0.0F) GL11.glDisable(GL11.GL_SCISSOR_TEST); } - protected void drawGradientRect(int left, int top, int right, int bottom, int color1, int color2) + protected boolean drawTopBottomShadow(Tessellator tess) + { + return true; + } + + protected boolean drawBackground(Tessellator tess) + { + return true; + } + + protected boolean shouldCenterShortContent() + { + return true; + } + + protected int getListLeft() + { + return this.left; + } + + protected int getListRight() + { + return this.right - 7; + } + + /** + * Returns the x-coordinate passed to entry renderers. + * This may be inset from {@link #getListLeft()}. + */ + protected int getListContentLeft() + { + return this.getListLeft(); + } + + public int getListWidth() + { + return this.listWidth; + } + + protected int getScrollbarLeft() + { + return this.right - 6; + } + + public int getMaxScroll() + { + return Math.max(0, this.getContentHeight() - (this.bottom - this.top - 4)); + } + + public void setAmountScrolled(float amount) + { + this.scrollDistance = MathHelper.clamp(amount, 0, this.getMaxScroll()); + } + + public void clampAmountScrolled() { - GuiUtils.drawGradientRect(0, left, top, right, bottom, color1, color2); + this.setAmountScrolled(this.scrollDistance); + } + + public void setLeft(int left) + { + int width = this.right - this.left; + this.left = left; + this.right = left + width; + this.clampAmountScrolled(); + } + + public void setWidth(int width) + { + this.right = this.left + width; + this.clampAmountScrolled(); + } + + public void setHeight(int height) + { + this.bottom = this.top + height; + this.clampAmountScrolled(); + } + + public void setVisible(boolean visible) { + this.visible = visible; + } + + protected int getScrollThumbHeight() + { + int viewHeight = this.bottom - this.top; + int height = viewHeight * viewHeight / this.getContentHeight(); + + if (height < 32) height = 32; + if (height > viewHeight - 8) height = viewHeight - 8; + return height; } } diff --git a/src/main/java/net/minecraftforge/fml/client/GuiSlotModList.java b/src/main/java/net/minecraftforge/fml/client/GuiSlotModList.java index 7ea8efad7..86d3b769f 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiSlotModList.java +++ b/src/main/java/net/minecraftforge/fml/client/GuiSlotModList.java @@ -95,9 +95,9 @@ ArrayList getMods() } @Override - protected void drawSlot(int idx, int right, int top, int height, Tessellator tess) + protected void drawSlot(int slotIndex, int right, int top, int height, Tessellator tess, float partialTicks) { - ModContainer mc = mods.get(idx); + ModContainer mc = mods.get(slotIndex); String name = StringUtils.stripControlCodes(mc.getName()); String version = StringUtils.stripControlCodes(Strings.isNullOrEmpty(mc.getDisplayVersion()) ? mc.getVersion() : mc.getDisplayVersion()); FontRenderer font = this.parent.getFontRenderer();