package de.take_weiland.mods.commons.client;
import com.google.common.collect.Lists;
import de.take_weiland.mods.commons.util.SCReflector;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.util.MathHelper;
import java.util.List;
import static de.take_weiland.mods.commons.client.Guis.isPointInRegion;
import static org.lwjgl.opengl.GL11.*;
public abstract class ScrollPane extends Gui {
private boolean clip;
protected int x;
protected int y;
protected int width;
protected int height;
protected int contentHeight;
protected int scrollbarWidth = 10;
protected int scrollbarHeight = 30;
private int scrollbarClickOffset = 0;
private int scrollbarY = 0;
private boolean isDragging = false;
private final GuiScreen screen;
protected final Minecraft mc = Minecraft.getMinecraft();
private final List<GuiButton> buttons = Lists.newArrayList();
public ScrollPane(GuiScreen screen, int x, int y, int width, int height, int contentHeight) {
this.screen = screen;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.contentHeight = contentHeight;
}
private int newScrollIfInside;
public final void onMouseWheel(int dWheel) {
if (needsScrollbar() && dWheel != 0) {
dWheel = -Integer.signum(dWheel) * 5;
newScrollIfInside = MathHelper.clamp_int(scrollbarY + dWheel, -1, height - scrollbarHeight);
}
}
public final void draw(int mouseX, int mouseY) {
if (newScrollIfInside >= 0 && Guis.isPointInRegion(x, y, width, height, mouseX, mouseY)) {
scrollbarY = newScrollIfInside;
newScrollIfInside = -1;
}
float yTranslate = computeYTranslate();
mouseX -= x;
mouseY -= yTranslate;
glColor3f(1, 1, 1);
int scale = Guis.computeGuiScale();
if (clip) {
glScissor(0, mc.displayHeight - (y + height) * scale, (width + x) * scale, height * scale);
glEnable(GL_SCISSOR_TEST);
}
glPushMatrix();
glTranslatef(x, yTranslate, 0);
drawInternal(mouseX, mouseY);
glPopMatrix();
if (clip) {
glDisable(GL_SCISSOR_TEST);
}
if (needsScrollbar()) {
int scrollbarX = x + (width - scrollbarWidth);
drawScrollbar(scrollbarX, y + scrollbarY, scrollbarX + scrollbarWidth, y + scrollbarY + scrollbarHeight);
}
}
private float computeYTranslate() {
return y - ((scrollbarY) / (float) (height - scrollbarHeight)) * (contentHeight - height);
}
private void drawInternal(int mouseX, int mouseY) {
drawImpl(mouseX, mouseY);
int n = buttons.size();
for (int i = 0; i < n; ++i) {
buttons.get(i).drawButton(mc, mouseX, mouseY);
}
}
private boolean needsScrollbar() {
return height < contentHeight;
}
public final void onMouseClick(int mouseX, int mouseY, int btn) {
if (btn == 0 && needsScrollbar()) {
if (Guis.isPointInRegion(x + (width - scrollbarWidth), y + scrollbarY, scrollbarWidth, scrollbarHeight, mouseX, mouseY)) {
isDragging = true;
scrollbarClickOffset = mouseY - (y + scrollbarY);
}
}
mouseX -= x;
mouseY -= computeYTranslate();
if (isPointInRegion(0, 0, width, height, mouseX, mouseY)) {
for (GuiButton button : buttons) {
if (button.mousePressed(mc, mouseX, mouseY)) {
SCReflector.instance.actionPerformed(screen, button);
}
}
}
handleMouseClick(mouseX, mouseY, btn);
}
public final void onMouseBtnReleased(int btn) {
if (btn == 0) {
isDragging = false;
}
}
public final void onMouseMoved(int mouseX, int mouseY) {
if (isDragging) {
scrollbarY = MathHelper.clamp_int(mouseY - y - scrollbarClickOffset, 0, height - scrollbarHeight);
}
}
public final void setScrollbarWidth(int scrollbarWidth) {
this.scrollbarWidth = scrollbarWidth;
}
public final void setX(int x) {
this.x = x;
}
public final void setY(int y) {
this.y = y;
}
public final void setWidth(int width) {
this.width = width;
}
public final void setHeight(int height) {
if (this.height != height) {
recalcScrollbar();
}
this.height = height;
}
public final void setContentHeight(int contentHeight) {
if (this.contentHeight != contentHeight) {
recalcScrollbar();
}
this.contentHeight = contentHeight;
}
private void recalcScrollbar() {
scrollbarY = 0;
isDragging = false;
}
public final void clearButtons() {
buttons.clear();
}
public final void addButton(GuiButton button) {
buttons.add(button);
}
public final void setClip(boolean clip) {
this.clip = clip;
}
protected void drawScrollbar(int x, int y, int x2, int y2) {
drawRect(x, y, x2, y2, 0xff000000);
drawRect(x, y, x + 1, y2, 0xff444444);
drawRect(x2 - 1, y, x2, y2, 0xff444444);
drawRect(x, y, x2, y + 1, 0xff444444);
drawRect(x, y2 - 1, x2, y2, 0xff444444);
}
protected void drawImpl(int mouseX, int mouseY) {
drawImpl();
}
protected abstract void drawImpl();
protected void handleMouseClick(int relX, int relY, int btn) {
}
}