tcr/java/src/game/gui/element/GuiList.java

415 lines
17 KiB
Java
Raw Normal View History

2025-03-11 14:09:49 +01:00
package game.gui.element;
import java.util.List;
2025-03-19 22:40:25 +01:00
import org.lwjgl.opengl.GL11;
import game.collect.Lists;
2025-03-16 17:40:47 +01:00
2025-03-11 14:09:49 +01:00
import game.gui.Gui;
import game.renderer.DefaultVertexFormats;
import game.renderer.Drawing;
import game.renderer.GlState;
2025-03-16 17:45:08 +01:00
import game.renderer.RenderBuffer;
2025-03-11 14:09:49 +01:00
import game.renderer.Tessellator;
import game.util.ExtMath;
import game.window.Button;
public abstract class GuiList<T extends ListEntry> extends Gui
{
protected final List<T> elements = Lists.newArrayList();
protected int width;
protected int height;
protected int top;
protected int bottom;
protected int right;
protected int left;
protected int mouseX;
protected int mouseY;
protected int initialClickY = -2;
protected float scrollMultiplier;
protected float amountScrolled;
protected int selectedElement = -1;
protected long lastClicked;
public abstract int getListWidth(); // 220
public abstract int getSlotHeight();
protected int getScrollBarX()
{
return 0;
}
public void setDimensions(int widthIn, int heightIn, int topIn, int bottomIn)
{
this.width = widthIn;
this.height = heightIn;
this.top = topIn;
this.bottom = bottomIn;
this.left = 0;
this.right = widthIn;
}
public void init(int width, int height) {
this.selectedElement = -1;
}
public void setSlotXBoundsFromLeft(int leftIn)
{
this.left = leftIn;
this.right = leftIn + this.width;
}
public final T getListEntry(int index) {
return this.elements.get(index);
}
public final T getSelected() {
return this.selectedElement < 0 ? null : this.elements.get(this.selectedElement);
}
public final int getSize() {
return this.elements.size();
}
2025-03-18 17:42:21 +01:00
public final void setSelected(int index) {
this.selectedElement = index;
}
2025-03-11 14:09:49 +01:00
protected int getContentHeight()
{
return this.getSize() * this.getSlotHeight();
}
public int getSlotIndexFromScreenCoords(int x, int y)
{
int i = this.left + this.width / 2 - this.getListWidth() / 2;
int j = this.left + this.width / 2 + this.getListWidth() / 2;
int k = y - this.top + (int)this.amountScrolled - 4;
int l = k / this.getSlotHeight();
return this.isInList(x, y) && x >= i && x <= j && l >= 0 && k >= 0 && l < this.getSize() ? l : -1;
}
protected boolean isInList(int x, int y)
{
return x >= this.getScrollBarX() + 6; // x < this.getScrollBarX();
}
protected final boolean isSelected(int slotIndex)
{
return slotIndex == this.selectedElement;
}
protected void bindAmountScrolled()
{
this.amountScrolled = ExtMath.clampf(this.amountScrolled, 0.0F, (float)this.getMaxScroll());
}
public int getMaxScroll()
{
return Math.max(0, this.getContentHeight() - (this.bottom - this.top - 4));
}
public int getAmountScrolled()
{
return (int)this.amountScrolled;
}
public boolean isMouseYWithinSlotBounds(int p_148141_1_)
{
return p_148141_1_ >= this.top && p_148141_1_ <= this.bottom && this.mouseX >= this.left && this.mouseX <= this.right;
}
public void scrollBy(int amount)
{
this.amountScrolled += (float)amount;
this.bindAmountScrolled();
this.initialClickY = -2;
}
// public void actionPerformed(Button button)
// {
// if (button.enabled)
// {
// if (button.id == this.scrollUpButtonID)
// {
// this.amountScrolled -= (float)(this.slotHeight * 2 / 3);
// this.initialClickY = -2;
// this.bindAmountScrolled();
// }
// else if (button.id == this.scrollDownButtonID)
// {
// this.amountScrolled += (float)(this.slotHeight * 2 / 3);
// this.initialClickY = -2;
// this.bindAmountScrolled();
// }
// }
// }
public void draw()
{
int mouseXIn = this.gm.mouse_x;
int mouseYIn = this.gm.mouse_y;
this.mouseX = mouseXIn;
this.mouseY = mouseYIn;
this.drawBackground();
int i = this.getScrollBarX();
int j = i + 6;
this.bindAmountScrolled();
GlState.disableLighting();
GlState.disableFog();
GlState.enableTexture2D();
RenderBuffer worldrenderer = Tessellator.getBuffer();
this.gm.getTextureManager().bindTexture(Gui.DIRT_BACKGROUND);
GlState.color(1.0F, 1.0F, 1.0F, 1.0F);
float f = 32.0F;
2025-03-19 23:49:49 +01:00
worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
2025-03-27 23:14:26 +01:00
worldrenderer.pos((double)0, (double)this.bottom, 0.0D).tex((double)((float)0 / f), (double)((float)(this.bottom + (int)this.amountScrolled) / f)).color(32, 32, 32, 255).endVertex();
worldrenderer.pos((double)this.gm.fb_x, (double)this.bottom, 0.0D).tex((double)((float)this.gm.fb_x / f), (double)((float)(this.bottom + (int)this.amountScrolled) / f)).color(32, 32, 32, 255).endVertex();
worldrenderer.pos((double)this.gm.fb_x, (double)this.top, 0.0D).tex((double)((float)this.gm.fb_x / f), (double)((float)(this.top + (int)this.amountScrolled) / f)).color(32, 32, 32, 255).endVertex();
worldrenderer.pos((double)0, (double)this.top, 0.0D).tex((double)((float)0 / f), (double)((float)(this.top + (int)this.amountScrolled) / f)).color(32, 32, 32, 255).endVertex();
2025-03-11 14:09:49 +01:00
Tessellator.draw();
int x = this.left + this.width / 2 - this.getListWidth() / 2 + 2;
int y = this.top + 4 - (int)this.amountScrolled;
this.drawSelectionBox(x, y, mouseXIn, mouseYIn);
GlState.disableDepth();
this.overlayBackground(0, this.top, 255, 255);
this.overlayBackground(this.bottom, this.height, 255, 255);
GlState.enableBlend();
2025-03-19 23:31:33 +01:00
GlState.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ZERO, GL11.GL_ONE);
2025-03-11 14:09:49 +01:00
GlState.disableAlpha();
2025-03-19 22:40:25 +01:00
GlState.shadeModel(GL11.GL_SMOOTH);
2025-03-11 14:09:49 +01:00
GlState.disableTexture2D();
int i1 = 4;
2025-03-19 23:49:49 +01:00
worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
2025-03-27 23:14:26 +01:00
worldrenderer.pos((double)0, (double)(this.top + i1), 0.0D).tex(0.0D, 1.0D).color(0, 0, 0, 0).endVertex();
worldrenderer.pos((double)this.gm.fb_x, (double)(this.top + i1), 0.0D).tex(1.0D, 1.0D).color(0, 0, 0, 0).endVertex();
worldrenderer.pos((double)this.gm.fb_x, (double)this.top, 0.0D).tex(1.0D, 0.0D).color(0, 0, 0, 255).endVertex();
worldrenderer.pos((double)0, (double)this.top, 0.0D).tex(0.0D, 0.0D).color(0, 0, 0, 255).endVertex();
2025-03-11 14:09:49 +01:00
Tessellator.draw();
2025-03-19 23:49:49 +01:00
worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
2025-03-27 23:14:26 +01:00
worldrenderer.pos((double)0, (double)this.bottom, 0.0D).tex(0.0D, 1.0D).color(0, 0, 0, 255).endVertex();
worldrenderer.pos((double)this.gm.fb_x, (double)this.bottom, 0.0D).tex(1.0D, 1.0D).color(0, 0, 0, 255).endVertex();
worldrenderer.pos((double)this.gm.fb_x, (double)(this.bottom - i1), 0.0D).tex(1.0D, 0.0D).color(0, 0, 0, 0).endVertex();
worldrenderer.pos((double)0, (double)(this.bottom - i1), 0.0D).tex(0.0D, 0.0D).color(0, 0, 0, 0).endVertex();
2025-03-11 14:09:49 +01:00
Tessellator.draw();
int j1 = this.getMaxScroll();
if (j1 > 0)
{
int k1 = (this.bottom - this.top) * (this.bottom - this.top) / this.getContentHeight();
k1 = ExtMath.clampi(k1, 32, this.bottom - this.top - 8);
int l1 = (int)this.amountScrolled * (this.bottom - this.top - k1) / j1 + this.top;
if (l1 < this.top)
{
l1 = this.top;
}
2025-03-19 23:49:49 +01:00
worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
2025-03-11 14:09:49 +01:00
worldrenderer.pos((double)i, (double)this.bottom, 0.0D).tex(0.0D, 1.0D).color(0, 0, 0, 255).endVertex();
worldrenderer.pos((double)j, (double)this.bottom, 0.0D).tex(1.0D, 1.0D).color(0, 0, 0, 255).endVertex();
worldrenderer.pos((double)j, (double)this.top, 0.0D).tex(1.0D, 0.0D).color(0, 0, 0, 255).endVertex();
worldrenderer.pos((double)i, (double)this.top, 0.0D).tex(0.0D, 0.0D).color(0, 0, 0, 255).endVertex();
Tessellator.draw();
2025-03-19 23:49:49 +01:00
worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
2025-03-11 14:09:49 +01:00
worldrenderer.pos((double)i, (double)(l1 + k1), 0.0D).tex(0.0D, 1.0D).color(128, 128, 128, 255).endVertex();
worldrenderer.pos((double)j, (double)(l1 + k1), 0.0D).tex(1.0D, 1.0D).color(128, 128, 128, 255).endVertex();
worldrenderer.pos((double)j, (double)l1, 0.0D).tex(1.0D, 0.0D).color(128, 128, 128, 255).endVertex();
worldrenderer.pos((double)i, (double)l1, 0.0D).tex(0.0D, 0.0D).color(128, 128, 128, 255).endVertex();
Tessellator.draw();
2025-03-19 23:49:49 +01:00
worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
2025-03-11 14:09:49 +01:00
worldrenderer.pos((double)i, (double)(l1 + k1 - 1), 0.0D).tex(0.0D, 1.0D).color(192, 192, 192, 255).endVertex();
worldrenderer.pos((double)(j - 1), (double)(l1 + k1 - 1), 0.0D).tex(1.0D, 1.0D).color(192, 192, 192, 255).endVertex();
worldrenderer.pos((double)(j - 1), (double)l1, 0.0D).tex(1.0D, 0.0D).color(192, 192, 192, 255).endVertex();
worldrenderer.pos((double)i, (double)l1, 0.0D).tex(0.0D, 0.0D).color(192, 192, 192, 255).endVertex();
Tessellator.draw();
}
GlState.enableTexture2D();
2025-03-19 22:40:25 +01:00
GlState.shadeModel(GL11.GL_FLAT);
2025-03-11 14:09:49 +01:00
GlState.enableAlpha();
GlState.disableBlend();
super.draw();
}
public void handleMouseInput()
{
if (this.isMouseYWithinSlotBounds(this.mouseY))
{
// if (Button.MOUSE_LEFT.isDown() && this.getEnabled())
// {
if (this.initialClickY == -1)
{
boolean flag1 = true;
if (this.mouseY >= this.top && this.mouseY <= this.bottom)
{
int j2 = (this.width - this.getListWidth()) / 2;
int k2 = (this.width + this.getListWidth()) / 2;
int l2 = this.mouseY - this.top + (int)this.amountScrolled - 4;
int i1 = l2 / this.getSlotHeight();
if (i1 < this.getSize() && this.mouseX >= j2 && this.mouseX <= k2 && i1 >= 0 && l2 >= 0)
{
}
else if (this.mouseX >= j2 && this.mouseX <= k2 && l2 < 0)
{
flag1 = false;
}
int i3 = this.getScrollBarX();
int j1 = i3 + 6;
if (this.mouseX >= i3 && this.mouseX <= j1)
{
this.scrollMultiplier = -1.0F;
int k1 = this.getMaxScroll();
if (k1 < 1)
{
k1 = 1;
}
int l1 = (int)((float)((this.bottom - this.top) * (this.bottom - this.top)) / (float)this.getContentHeight());
l1 = ExtMath.clampi(l1, 32, this.bottom - this.top - 8);
this.scrollMultiplier /= (float)(this.bottom - this.top - l1) / (float)k1;
}
else
{
this.scrollMultiplier = 1.0F;
}
if (flag1)
{
this.initialClickY = this.mouseY;
}
else
{
this.initialClickY = -2;
}
}
else
{
this.initialClickY = -2;
}
}
else if (this.initialClickY >= 0)
{
this.amountScrolled -= (float)(this.mouseY - this.initialClickY) * this.scrollMultiplier;
this.initialClickY = this.mouseY;
}
// }
// else
// {
// this.initialClickY = -1;
// }
}
}
protected void drawSelectionBox(int x, int y, int mouseXIn, int mouseYIn)
{
int size = this.getSize();
RenderBuffer rb = Tessellator.getBuffer();
for (int z = 0; z < size; z++)
{
int y1 = y + z * this.getSlotHeight();
int h = this.getSlotHeight() - 4;
if (this.isSelected(z))
{
int x1 = this.left + (this.width / 2 - this.getListWidth() / 2);
int x2 = this.left + this.width / 2 + this.getListWidth() / 2;
GlState.color(1.0F, 1.0F, 1.0F, 1.0F);
GlState.disableTexture2D();
2025-03-19 23:49:49 +01:00
rb.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
2025-03-11 14:09:49 +01:00
rb.pos((double)x1, (double)(y1 + h + 2), 0.0D).tex(0.0D, 1.0D).color(128, 128, 128, 255).endVertex();
rb.pos((double)x2, (double)(y1 + h + 2), 0.0D).tex(1.0D, 1.0D).color(128, 128, 128, 255).endVertex();
rb.pos((double)x2, (double)(y1 - 2), 0.0D).tex(1.0D, 0.0D).color(128, 128, 128, 255).endVertex();
rb.pos((double)x1, (double)(y1 - 2), 0.0D).tex(0.0D, 0.0D).color(128, 128, 128, 255).endVertex();
rb.pos((double)(x1 + 1), (double)(y1 + h + 1), 0.0D).tex(0.0D, 1.0D).color(0, 0, 0, 255).endVertex();
rb.pos((double)(x2 - 1), (double)(y1 + h + 1), 0.0D).tex(1.0D, 1.0D).color(0, 0, 0, 255).endVertex();
rb.pos((double)(x2 - 1), (double)(y1 - 1), 0.0D).tex(1.0D, 0.0D).color(0, 0, 0, 255).endVertex();
rb.pos((double)(x1 + 1), (double)(y1 - 1), 0.0D).tex(0.0D, 0.0D).color(0, 0, 0, 255).endVertex();
Tessellator.draw();
GlState.enableTexture2D();
}
boolean hover = this.getSlotIndexFromScreenCoords(mouseXIn, mouseYIn) == z;
this.getListEntry(z).draw(x, y1, mouseXIn - x, mouseYIn - y1, hover);
if(hover)
2025-03-20 15:33:08 +01:00
Drawing.drawRect(x - 2, y1 - 2, this.getListWidth(), this.getSlotHeight(), Gui.HOVER_COLOR);
2025-03-11 14:09:49 +01:00
}
}
protected void overlayBackground(int startY, int endY, int startAlpha, int endAlpha)
{
RenderBuffer rb = Tessellator.getBuffer();
this.gm.getTextureManager().bindTexture(Gui.DIRT_BACKGROUND);
GlState.color(1.0F, 1.0F, 1.0F, 1.0F);
float f = 32.0F;
2025-03-19 23:49:49 +01:00
rb.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
2025-03-27 23:14:26 +01:00
rb.pos((double)0, (double)endY, 0.0D).tex(0.0D, (double)((float)endY / 32.0F)).color(64, 64, 64, endAlpha).endVertex();
rb.pos((double)this.gm.fb_x, (double)endY, 0.0D).tex((double)((float)this.gm.fb_x / 32.0F), (double)((float)endY / 32.0F)).color(64, 64, 64, endAlpha).endVertex();
rb.pos((double)this.gm.fb_x, (double)startY, 0.0D).tex((double)((float)this.gm.fb_x / 32.0F), (double)((float)startY / 32.0F)).color(64, 64, 64, startAlpha).endVertex();
rb.pos((double)0, (double)startY, 0.0D).tex(0.0D, (double)((float)startY / 32.0F)).color(64, 64, 64, startAlpha).endVertex();
2025-03-11 14:09:49 +01:00
Tessellator.draw();
}
public void mouse(Button btn, int x, int y, boolean ctrl, boolean shift)
{
super.mouse(btn, x, y, ctrl, shift);
if (this.isMouseYWithinSlotBounds(y))
{
int i = this.getSlotIndexFromScreenCoords(x, y);
if (i >= 0)
{
int j = this.left + this.width / 2 - this.getListWidth() / 2 + 2;
int k = this.top + 4 - this.getAmountScrolled() + i * this.getSlotHeight();
int l = x - j;
int i1 = y - k;
boolean flag = i == this.selectedElement && System.currentTimeMillis() - this.lastClicked < (long)this.gm.dclickDelay;
this.selectedElement = i;
this.lastClicked = System.currentTimeMillis();
this.getListEntry(i).select(flag, l, i1);
}
}
if(btn == Button.MOUSE_LEFT && this.clicked(x, y) == null)
this.handleMouseInput();
}
public void mouserel(Button btn, int x, int y) {
super.mouserel(btn, x, y);
if(btn == Button.MOUSE_LEFT)
this.initialClickY = -1;
}
public void scroll(int scr_x, int scr_y, int x, int y, boolean ctrl, boolean shift) {
super.scroll(scr_x, scr_y, x, y, ctrl, shift);
if(scr_y != 0 && this.clicked(x, y) == null)
this.amountScrolled -= (float)(ExtMath.clampi(scr_y, -1, 1) * this.getSlotHeight() / 2);
}
public void drag(int x, int y) {
super.drag(x, y);
if(this.selected == null && Button.MOUSE_LEFT.isDown())
this.handleMouseInput();
}
}