package com.dynious.versionchecker.client.gui; import com.dynious.versionchecker.lib.Resources; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; import java.util.List; public abstract class GuiScroll { protected final Minecraft client; protected final int listWidth; protected final int listHeight; protected final int top; protected final int bottom; private final int right; protected final int left; protected final int slotHeight; private int scrollUpActionId; private int scrollDownActionId; protected int mouseX; protected int mouseY; private float initialMouseClickY = -2.0F; private float scrollFactor; private float scrollDistance; private int selectedIndex = -1; private long lastClickTime = 0L; private boolean isSelectable = true; private boolean hasCustomHeader; private int customHeaderHeight; public boolean disableInput = false; protected int horizontalPadding; protected int verticalPadding; public GuiScroll(Minecraft client, int width, int height, int top, int bottom, int left, int entryHeight) { this.client = client; this.listWidth = width; this.listHeight = height; this.top = top; this.bottom = bottom; this.slotHeight = entryHeight; this.left = left; this.right = width + this.left; } public void setSelectable(boolean isSelectable) { this.isSelectable = isSelectable; } protected void setHasCustomHeader(boolean hasCustomHeader, int customHeaderHeight) { this.hasCustomHeader = hasCustomHeader; this.customHeaderHeight = hasCustomHeader ? customHeaderHeight : 0; } public void setPadding(int horizontalPadding, int verticalPadding) { this.horizontalPadding = horizontalPadding; this.verticalPadding = verticalPadding; } protected abstract int getSize(); protected int getSlotHeight(int slotIndex) { return slotHeight; } protected abstract void elementClicked(int index, boolean doubleClick); protected abstract boolean isSelected(int index); protected int getContentHeight() { int contentHeight = 0; for (int slotIndex = 0; slotIndex < getSize(); slotIndex++) { contentHeight += getSlotHeight(slotIndex); } return contentHeight + customHeaderHeight; } protected abstract void drawBackground(); protected abstract void drawSlot(int slotIndex, int minX, int maxX, int minY, int maxY, Tessellator tesselator); protected void drawCustomHeader(int maxX, int topY, Tessellator tesselator) { } protected void onMouseDownOutsideOfSlots(int relativeX, int relativeY) { } protected void drawForeground(int mouseX, int mouseY) { } public int getSlotIndexAtPosition(int x, int y) { int minX = this.left + 1 + horizontalPadding; int maxX = this.left + this.listWidth - 7 - horizontalPadding; if (mouseX >= minX && mouseX <= maxX) { int relativeY = y - this.top - this.customHeaderHeight - verticalPadding + (int) this.scrollDistance; int currentTopY = 0; for (int slotIndex = 0; slotIndex < getSize(); slotIndex++) { int currentBottomY = currentTopY + getSlotHeight(slotIndex); if (relativeY >= currentTopY && relativeY < currentBottomY) return slotIndex; currentTopY = currentBottomY; } } return -1; } public void registerScrollButtons(@SuppressWarnings("rawtypes") List p_22240_1_, int scrollUpActionId, int scrollDownActionId) { this.scrollUpActionId = scrollUpActionId; this.scrollDownActionId = scrollDownActionId; } private void applyScrollLimits() { float maxScrollDistance = getMaxScrollDistance(); if (maxScrollDistance > 0) scrollDistance = Math.max(0, Math.min(getMaxScrollDistance(), scrollDistance)); else scrollDistance = maxScrollDistance / 2; } public void actionPerformed(GuiButton button) { if (button.enabled) { if (button.id == this.scrollUpActionId) { this.scrollDistance -= (float) (this.slotHeight * 2 / 3); this.initialMouseClickY = -2.0F; this.applyScrollLimits(); } else if (button.id == this.scrollDownActionId) { this.scrollDistance += (float) (this.slotHeight * 2 / 3); this.initialMouseClickY = -2.0F; this.applyScrollLimits(); } } } public float getMaxScrollDistance() { return getContentHeight() - getVisibleHeight() + verticalPadding * 2; } public int getVisibleHeight() { return bottom - top; } public int getScrollBarHeight() { int scrollBarHeight = (int) ((float) (getVisibleHeight() * getVisibleHeight()) / (float) getContentHeight()); scrollBarHeight = Math.max(32, Math.min(getVisibleHeight() - 8, scrollBarHeight)); return scrollBarHeight; } public void drawScreen(int mouseX, int mouseY, float p_22243_3_) { this.mouseX = mouseX; this.mouseY = mouseY; this.drawBackground(); int listLength = this.getSize(); int scrollBarXStart = this.left + this.listWidth - 6; int scrollBarXEnd = scrollBarXStart + 6; int boxLeft = this.left + horizontalPadding; int boxRight = scrollBarXStart - 1 - horizontalPadding; if (!disableInput) { if (Mouse.isButtonDown(0)) { // this is the case when the mouse was not down last frame if (this.initialMouseClickY == -1.0F) { if (mouseX >= scrollBarXStart && mouseX <= scrollBarXEnd && mouseY >= this.top && mouseY <= this.bottom) { this.scrollFactor = -1.0F / ((float) (getVisibleHeight() - getScrollBarHeight()) / (float) Math.max(1, getMaxScrollDistance())); this.initialMouseClickY = (float) mouseY; } else { int clickedSlotIndex = getSlotIndexAtPosition(mouseX, mouseY); if (clickedSlotIndex >= 0) { boolean isDoubleClick = clickedSlotIndex == this.selectedIndex && System.currentTimeMillis() - this.lastClickTime < 250L; this.elementClicked(clickedSlotIndex, isDoubleClick); this.selectedIndex = clickedSlotIndex; this.lastClickTime = System.currentTimeMillis(); } else { this.onMouseDownOutsideOfSlots(mouseX - boxLeft, mouseY - this.top + (int) this.scrollDistance); } // -2 will disable scrolling until the mouse is released this.initialMouseClickY = -2.0F; } } else if (this.initialMouseClickY >= 0.0F) { this.scrollDistance -= ((float) mouseY - this.initialMouseClickY) * this.scrollFactor; this.initialMouseClickY = (float) mouseY; } } // mouse is not down else { // scroll wheel while (Mouse.next()) { int deltaZ = -Mouse.getEventDWheel(); deltaZ = deltaZ > 0 ? 1 : (deltaZ < 0 ? -1 : 0); this.scrollDistance += (float) (getSize() < 20 ? deltaZ * this.slotHeight * 2 : deltaZ * this.getContentHeight() / 20f); } // will try to initialize scrolling on next mouse click this.initialMouseClickY = -1.0F; } } this.applyScrollLimits(); Tessellator tess = Tessellator.getInstance(); BufferBuilder worldr = tess.getBuffer(); // Used to be WorldRenderer worldr = tess.getWorldRenderer(); if (this.client.world != null) { this.drawGradientRect(this.left, this.top, this.right, this.bottom, -1072689136, -804253680); } else { GL11.glDisable(GL11.GL_LIGHTING); GL11.glDisable(GL11.GL_FOG); this.client.renderEngine.bindTexture(Gui.OPTIONS_BACKGROUND); GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); float var17 = 32.0F; worldr.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); worldr.pos((double) this.left, (double) this.bottom, 0.0D).tex( (double) ((float) this.left / var17), (double) ((float) (this.bottom + (int) this.scrollDistance) / var17) ).color(0x20, 0x20, 0x20, 255).endVertex(); worldr.pos((double) this.right, (double) this.bottom, 0.0D).tex((double) ((float) this.right / var17), (double) ((float) (this.bottom + (int) this.scrollDistance) / var17)).color(0x20, 0x20, 0x20, 255).endVertex(); worldr.pos((double) this.right, (double) this.top, 0.0D).tex((double) ((float) this.right / var17), (double) ((float) (this.top + (int) this.scrollDistance) / var17)).color(0x20, 0x20, 0x20, 255).endVertex(); worldr.pos((double) this.left, (double) this.top, 0.0D).tex((double) ((float) this.left / var17), (double) ((float) (this.top + (int) this.scrollDistance) / var17)).color(0x20, 0x20, 0x20, 255).endVertex(); tess.draw(); } // boxRight = this.listWidth / 2 - 92 - 16; int topOffsetByScrollDistance = this.top - (int) this.scrollDistance; if (this.hasCustomHeader) { this.drawCustomHeader(boxRight, topOffsetByScrollDistance, tess); } int drawY = topOffsetByScrollDistance + customHeaderHeight + verticalPadding; for (int slotIndex = 0; slotIndex < listLength; ++slotIndex) { int curSlotHeight = getSlotHeight(slotIndex); if (drawY <= this.bottom && drawY + curSlotHeight >= this.top) { if (this.isSelectable && this.isSelected(slotIndex)) { GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); GL11.glDisable(GL11.GL_TEXTURE_2D); worldr.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); worldr.pos((double) boxLeft, (double) (drawY + curSlotHeight + 2), 0.0D).tex( 0.0D, 1.0D).color(0x80,0x80,0x80,255).endVertex(); worldr.pos((double) boxRight, (double) (drawY + curSlotHeight + 2), 0.0D).tex( 1.0D, 1.0D).color(0x80,0x80,0x80,255).endVertex(); worldr.pos((double) boxRight, (double) (drawY - 2), 0.0D).tex( 1.0D, 0.0D).color(0x80,0x80,0x80,255).endVertex(); worldr.pos((double) boxLeft, (double) (drawY - 2), 0.0D).tex( 0.0D, 0.0D).color(0x80,0x80,0x80,255).endVertex(); worldr.pos((double) (boxLeft + 1), (double) (drawY + curSlotHeight + 1), 0.0D).tex( 0.0D, 1.0D).color(0x80,0x80,0x80,255).endVertex(); worldr.pos((double) (boxRight - 1), (double) (drawY + curSlotHeight + 1), 0.0D).tex( 1.0D, 1.0D).color(0x80,0x80,0x80,255).endVertex(); worldr.pos((double) (boxRight - 1), (double) (drawY - 1), 0.0D).tex( 1.0D, 0.0D).color(0x80,0x80,0x80,255).endVertex(); worldr.pos((double) (boxLeft + 1), (double) (drawY - 1), 0.0D).tex(0.0D, 0.0D).color(0x80,0x80,0x80,255).endVertex(); tess.draw(); GL11.glEnable(GL11.GL_TEXTURE_2D); } this.drawSlot(slotIndex, boxLeft, boxRight, drawY, drawY + curSlotHeight, tess); } drawY += curSlotHeight; } GL11.glDisable(GL11.GL_DEPTH_TEST); byte fadeGradientHeight = 4; if (this.client.world == null) { this.overlayBackground(); } GL11.glEnable(GL11.GL_BLEND); GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GL11.glDisable(GL11.GL_ALPHA_TEST); GL11.glShadeModel(GL11.GL_SMOOTH); GL11.glDisable(GL11.GL_TEXTURE_2D); worldr.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); worldr.pos((double) this.left, (double) (this.top + fadeGradientHeight), 0.0D).tex( 0.0D, 1.0D).color(0,0,0,255).endVertex(); worldr.pos((double) this.right, (double) (this.top + fadeGradientHeight), 0.0D).tex( 1.0D, 1.0D).color(0,0,0,255).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 - fadeGradientHeight), 0.0D).tex( 1.0D, 0.0D).color(0,0,0,0).endVertex(); worldr.pos((double) this.left, (double) (this.bottom - fadeGradientHeight), 0.0D).tex( 0.0D, 0.0D).color(0,0,0,0).endVertex(); tess.draw(); float maxScrollDistance = getMaxScrollDistance(); if (maxScrollDistance > 0) { int scrollBarHeight = getScrollBarHeight(); int scrollBarTop = (int) (this.scrollDistance * (getVisibleHeight() - scrollBarHeight) / maxScrollDistance + this.top); scrollBarTop = Math.max(top, scrollBarTop); worldr.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); worldr.pos((double) scrollBarXStart, (double) this.bottom, 0.0D).tex( 0.0D, 1.0D).color(0,0,0,255).endVertex(); worldr.pos((double) scrollBarXEnd, (double) this.bottom, 0.0D).tex( 1.0D, 1.0D).color(0,0,0,255).endVertex(); worldr.pos((double) scrollBarXEnd, (double) this.top, 0.0D).tex( 1.0D, 0.0D).color(0,0,0,255).endVertex(); worldr.pos((double) scrollBarXStart, (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) scrollBarXStart, (double) (scrollBarTop + scrollBarHeight), 0.0D).tex( 0.0D, 1.0D).color(0x80,0x80,0x80,255).endVertex(); worldr.pos((double) scrollBarXEnd, (double) (scrollBarTop + scrollBarHeight), 0.0D).tex( 1.0D, 1.0D).color(0x80,0x80,0x80,255).endVertex(); worldr.pos((double) scrollBarXEnd, (double) scrollBarTop, 0.0D).tex( 1.0D, 0.0D).color(0x80,0x80,0x80,255).endVertex(); worldr.pos((double) scrollBarXStart, (double) scrollBarTop, 0.0D).tex( 0.0D, 0.0D).color(0x80,0x80,0x80,255).endVertex(); tess.draw(); worldr.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); worldr.pos((double) scrollBarXStart, (double) (scrollBarTop + scrollBarHeight - 1), 0.0D).tex( 0.0D, 1.0D).color(0xC0,0xC0,0xC0,255).endVertex(); worldr.pos((double) (scrollBarXEnd - 1), (double) (scrollBarTop + scrollBarHeight - 1), 0.0D).tex( 1.0D, 1.0D).color(0xC0,0xC0,0xC0,255).endVertex(); worldr.pos((double) (scrollBarXEnd - 1), (double) scrollBarTop, 0.0D).tex( 1.0D, 0.0D).color(0xC0,0xC0,0xC0,255).endVertex(); worldr.pos((double) scrollBarXStart, (double) scrollBarTop, 0.0D).tex( 0.0D, 0.0D).color(0xC0,0xC0,0xC0,255).endVertex(); tess.draw(); } this.drawForeground(mouseX, mouseY); GL11.glEnable(GL11.GL_TEXTURE_2D); GL11.glShadeModel(GL11.GL_FLAT); GL11.glEnable(GL11.GL_ALPHA_TEST); GL11.glDisable(GL11.GL_BLEND); } public void overlayBackground() { this.client.renderEngine.bindTexture(Resources.GUI_WINDOW); GL11.glColor4f(0.6F, 0.6F, 0.6F, 1.0F); Gui.drawModalRectWithCustomSizedTexture(left - 10, top - slotHeight, 0, 0, listWidth + 20, slotHeight, 220, 160); Gui.drawModalRectWithCustomSizedTexture(left - 10, top + listHeight, 0, listHeight + slotHeight, listWidth + 20, slotHeight, 220, 160); } protected void drawGradientRect(int par1, int par2, int par3, int par4, int par5, int par6) { int f = (par5 >> 24 & 255); float f1 = (float)(par5 >> 16 & 255) / 255.0F; float f2 = (float)(par5 >> 8 & 255) / 255.0F; float f3 = (float)(par5 & 255) / 255.0F; int f4 = (par6 >> 24 & 255); float f5 = (float)(par6 >> 16 & 255) / 255.0F; float f6 = (float)(par6 >> 8 & 255) / 255.0F; float f7 = (float)(par6 & 255) / 255.0F; GL11.glDisable(GL11.GL_TEXTURE_2D); GL11.glEnable(GL11.GL_BLEND); GL11.glDisable(GL11.GL_ALPHA_TEST); OpenGlHelper.glBlendFunc(770, 771, 1, 0); GL11.glShadeModel(GL11.GL_SMOOTH); Tessellator tessellator = Tessellator.getInstance(); BufferBuilder buffer = tessellator.getBuffer(); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR); //POSITION_TEX_COLOR? buffer.pos((double)par3, (double)par2, 0.0D).color(f1, f2, f3, f).endVertex(); buffer.pos((double)par1, (double)par2, 0.0D).color(f1, f2, f3, f).endVertex(); buffer.pos((double)par1, (double)par4, 0.0D).color(f5, f6, f7, f4).endVertex(); buffer.pos((double)par3, (double)par4, 0.0D).color(f5, f6, f7, f4).endVertex(); tessellator.draw(); GL11.glShadeModel(GL11.GL_FLAT); GL11.glDisable(GL11.GL_BLEND); GL11.glEnable(GL11.GL_ALPHA_TEST); GL11.glEnable(GL11.GL_TEXTURE_2D); } }