package eu.crushedpixel.replaymod.gui.elements; import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.gui.elements.listeners.SelectionListener; import eu.crushedpixel.replaymod.holders.GuiEntryListEntry; import eu.crushedpixel.replaymod.utils.MouseUtils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import org.lwjgl.input.Mouse; import org.lwjgl.util.Point; import java.awt.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class GuiDropdown extends GuiAdvancedTextField implements GuiOverlayElement { private final int visibleDropout; private final int dropoutElementHeight = 14; private final int maxDropoutHeight; private int selectionIndex = -1; private boolean open = false; private Minecraft mc = Minecraft.getMinecraft(); private List selectionListeners = new ArrayList(); private int upperIndex = 0; private List elements = new ArrayList(); private HashMap hoverTexts = new HashMap(); public GuiDropdown(FontRenderer fontRenderer, int xPos, int yPos, int width, int visibleDropout) { super(fontRenderer, xPos, yPos, width, 20); this.visibleDropout = visibleDropout; this.maxDropoutHeight = dropoutElementHeight * visibleDropout; } @Override public void drawTextBox() { if(elements.size() > selectionIndex && selectionIndex >= 0) { setText(mc.fontRendererObj.trimStringToWidth( elements.get(selectionIndex).getDisplayString(), width - 8)); } else { setText(""); } super.drawTextBox(); //Draw the right part of the Dropdown drawRect(xPosition + width - height, yPosition, xPosition + width, yPosition + height, -16777216); drawRect(xPosition + width - height, yPosition, this.xPosition + width - height + 1, yPosition + height, -6250336); //heroically draw the triangle line by line instead of using a texture for(int i = 0; i <= Math.ceil(height / 2) - 4; i++) { drawHorizontalLine(xPosition + width - height + i + 4, xPosition + width - i - 4, yPosition + (height / 4) + i + 2, -6250336); } boolean drawHover = false; Point hoverPos = null; String hoverText = null; if(open && elements.size() > 0) { //draw the dropout part when opened boolean drawScrollBar = false; int requiredHeight = elements.size() * dropoutElementHeight; if(requiredHeight > maxDropoutHeight) { requiredHeight = maxDropoutHeight; drawScrollBar = true; } //The light outline drawRect(xPosition - 1, yPosition + height, xPosition + width + 1, yPosition + height + requiredHeight + 1, -6250336); //The dark inside drawRect(xPosition, yPosition + height + 1, xPosition + width, yPosition + height + requiredHeight, -16777216); //The elements int y = 0; int i = 0; for(T obj : elements) { if(i < upperIndex) { i++; continue; } drawHorizontalLine(xPosition, xPosition + width, yPosition + height + y, -6250336); String toWrite = mc.fontRendererObj.trimStringToWidth(obj.getDisplayString(), width - 8); drawString(mc.fontRendererObj, toWrite, xPosition + 4, yPosition + height + y + 4, Color.WHITE.getRGB()); if(MouseUtils.isMouseWithinBounds(xPosition, yPosition + height + y, width, dropoutElementHeight)) { String hover = hoverTexts.get(i); if(hover != null) { Point mousePos = MouseUtils.getMousePos(); drawHover = true; hoverPos = mousePos; hoverText = hover; } } y += dropoutElementHeight; i++; if(y >= requiredHeight) { break; } } if(drawScrollBar) { //The scroll bar int dw = Mouse.getDWheel(); if(dw > 0) { dw = -1; } else if(dw < 0) { dw = 1; } upperIndex = Math.max(Math.min(upperIndex + dw, elements.size() - visibleDropout), 0); drawRect(xPosition + width - 3, yPosition + height + 1, xPosition + width, yPosition + height + requiredHeight, Color.DARK_GRAY.getRGB()); float visiblePerc = ((float) visibleDropout) / elements.size(); int barHeight = (int) (visiblePerc * (requiredHeight - 1)); float posPerc = ((float) upperIndex) / elements.size(); int barY = (int) (posPerc * (requiredHeight - 1)); drawRect(xPosition + width - 3, yPosition + height + barY, xPosition + width, yPosition + height + 2 + barY + barHeight, -6250336); } if(drawHover) { ReplayMod.tooltipRenderer.drawTooltip(hoverPos.getX(), hoverPos.getY(), hoverText, null, Color.WHITE); } } } @Override public boolean mouseClick(Minecraft mc, int mouseX, int mouseY, int button) { return mouseClickedResult(mouseX, mouseY); } public boolean mouseClickedResult(int xPos, int yPos) { if(!isEnabled) return false; boolean success = false; if(xPos > xPosition + width - height && xPos < xPosition + width && yPos > yPosition && yPos < yPosition + height) { open = !open; } else { if(xPos > xPosition && xPos < xPosition + width && open) { int requiredHeight = Math.min(maxDropoutHeight, elements.size() * dropoutElementHeight); if(yPos > yPosition + height && yPos < yPosition + height + requiredHeight) { this.selectionIndex = (int) Math.floor((yPos - (yPosition + height)) / dropoutElementHeight) + upperIndex; success = true; fireSelectionChangeEvent(); } open = false; } else { open = false; } } return success; } @Override public void setText(String text) { if(!getText().equals(text)) { super.setText(text); } } public void setElements(List elements) { this.elements = elements; if(selectionIndex == -1 && elements.size() > 0) { selectionIndex = 0; } } public void clearElements() { this.elements = new ArrayList(); selectionIndex = -1; } public void addElement(T element) { this.elements.add(element); if(selectionIndex == -1) { selectionIndex = 0; } } public void setHoverText(int index, String text) { hoverTexts.put(index, text); } public T getElement(int index) { return elements.get(index); } public List getAllElements() { return elements; } public int getSelectionIndex() { return selectionIndex; } public void setSelectionIndex(int index) { setSelectionIndexQuietly(index); fireSelectionChangeEvent(); } /** * Sets the selection index without notifying SelectionChangeListeners. * @param index The Selection Index */ public void setSelectionIndexQuietly(int index) { this.selectionIndex = index; if(selectionIndex < 0) selectionIndex = -1; if(selectionIndex >= elements.size()) selectionIndex = elements.size()-1; } private void fireSelectionChangeEvent() { for(SelectionListener listener : selectionListeners) { listener.onSelectionChanged(selectionIndex); } } public void addSelectionListener(SelectionListener listener) { this.selectionListeners.add(listener); } public boolean isExpanded() { return open; } }