ForgePatch/src/main/java/net/minecraftforge/client/gui/ScrollPanel.java

271 lines
11 KiB
Java

/*
* Minecraft Forge
* Copyright (c) 2016-2019.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.client.gui;
import java.util.Collections;
import java.util.List;
import org.lwjgl.opengl.GL11;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.client.gui.FocusableGui;
import net.minecraft.client.gui.IGuiEventListener;
import net.minecraft.client.gui.IRenderable;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraftforge.fml.client.gui.GuiUtils;
public abstract class ScrollPanel extends FocusableGui implements IRenderable
{
private final Minecraft client;
protected final int width;
protected final int height;
protected final int top;
protected final int bottom;
protected final int right;
protected final int left;
private boolean scrolling;
protected float scrollDistance;
protected boolean captureMouse = true;
protected final int border = 4;
private final int barWidth = 6;
private final int barLeft;
public ScrollPanel(Minecraft client, int width, int height, int top, int left)
{
this.client = client;
this.width = width;
this.height = height;
this.top = top;
this.left = left;
this.bottom = height + this.top;
this.right = width + this.left;
this.barLeft = this.left + this.width - barWidth;
}
protected abstract int getContentHeight();
protected void drawBackground() {}
/**
* 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.
* @param mouseY
* @param mouseX
*/
protected abstract void drawPanel(int entryRight, int relativeY, Tessellator tess, int mouseX, int mouseY);
protected boolean clickPanel(double mouseX, double mouseY, int button) { return false; }
private int getMaxScroll()
{
return this.getContentHeight() - (this.height - this.border);
}
private void applyScrollLimits()
{
int max = getMaxScroll();
if (max < 0)
{
max /= 2;
}
if (this.scrollDistance < 0.0F)
{
this.scrollDistance = 0.0F;
}
if (this.scrollDistance > max)
{
this.scrollDistance = max;
}
}
@Override
public boolean mouseScrolled(double mouseX, double mouseY, double scroll)
{
if (scroll != 0)
{
this.scrollDistance += -scroll * getScrollAmount();
applyScrollLimits();
return true;
}
return false;
}
protected int getScrollAmount()
{
return 20;
}
@Override
public boolean isMouseOver(double mouseX, double mouseY)
{
return mouseX >= this.left && mouseX <= this.left + this.width &&
mouseY >= this.top && mouseY <= this.bottom;
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (super.mouseClicked(mouseX, mouseY, button))
return true;
this.scrolling = button == 0 && mouseX >= barLeft && mouseX < barLeft + barWidth;
if (this.scrolling)
{
return true;
}
int mouseListY = ((int)mouseY) - this.top - this.getContentHeight() + (int)this.scrollDistance - border;
if (mouseX >= left && mouseX <= right && mouseListY < 0)
{
return this.clickPanel(mouseX - left, mouseY - this.top + (int)this.scrollDistance - border, button);
}
return false;
}
@Override
public boolean mouseReleased(double p_mouseReleased_1_, double p_mouseReleased_3_, int p_mouseReleased_5_) {
if (super.mouseReleased(p_mouseReleased_1_, p_mouseReleased_3_, p_mouseReleased_5_))
return true;
boolean ret = this.scrolling;
this.scrolling = false;
return ret;
}
private int getBarHeight()
{
int barHeight = (height * height) / this.getContentHeight();
if (barHeight < 32) barHeight = 32;
if (barHeight > height - border*2)
barHeight = height - border*2;
return barHeight;
}
@Override
public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY)
{
if (this.scrolling)
{
int maxScroll = height - getBarHeight();
double moved = deltaY / maxScroll;
this.scrollDistance += getMaxScroll() * moved;
applyScrollLimits();
return true;
}
return false;
}
@Override
public void render(int mouseX, int mouseY, float partialTicks)
{
this.drawBackground();
Tessellator tess = Tessellator.getInstance();
BufferBuilder worldr = tess.getBuffer();
double scale = client.func_228018_at_().getGuiScaleFactor();
GL11.glEnable(GL11.GL_SCISSOR_TEST);
GL11.glScissor((int)(left * scale), (int)(client.func_228018_at_().getFramebufferHeight() - (bottom * scale)),
(int)(width * scale), (int)(height * scale));
if (this.client.world != null)
{
this.drawGradientRect(this.left, this.top, this.right, this.bottom, 0xC0101010, 0xD0101010);
}
else // Draw dark dirt background
{
RenderSystem.disableLighting();
RenderSystem.disableFog();
this.client.getTextureManager().bindTexture(AbstractGui.BACKGROUND_LOCATION);
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
final float texScale = 32.0F;
worldr.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
worldr.func_225582_a_(this.left, this.bottom, 0.0D).func_225583_a_(this.left / texScale, (this.bottom + (int)this.scrollDistance) / texScale).func_225586_a_(0x20, 0x20, 0x20, 0xFF).endVertex();
worldr.func_225582_a_(this.right, this.bottom, 0.0D).func_225583_a_(this.right / texScale, (this.bottom + (int)this.scrollDistance) / texScale).func_225586_a_(0x20, 0x20, 0x20, 0xFF).endVertex();
worldr.func_225582_a_(this.right, this.top, 0.0D).func_225583_a_(this.right / texScale, (this.top + (int)this.scrollDistance) / texScale).func_225586_a_(0x20, 0x20, 0x20, 0xFF).endVertex();
worldr.func_225582_a_(this.left, this.top, 0.0D).func_225583_a_(this.left / texScale, (this.top + (int)this.scrollDistance) / texScale).func_225586_a_(0x20, 0x20, 0x20, 0xFF).endVertex();
tess.draw();
}
int baseY = this.top + border - (int)this.scrollDistance;
this.drawPanel(right, baseY, tess, mouseX, mouseY);
RenderSystem.disableDepthTest();
int extraHeight = (this.getContentHeight() + border) - height;
if (extraHeight > 0)
{
int barHeight = getBarHeight();
int barTop = (int)this.scrollDistance * (height - barHeight) / extraHeight + this.top;
if (barTop < this.top)
{
barTop = this.top;
}
RenderSystem.disableTexture();
worldr.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
worldr.func_225582_a_(barLeft, this.bottom, 0.0D).func_225583_a_(0.0F, 1.0F).func_225586_a_(0x00, 0x00, 0x00, 0xFF).endVertex();
worldr.func_225582_a_(barLeft + barWidth, this.bottom, 0.0D).func_225583_a_(1.0F, 1.0F).func_225586_a_(0x00, 0x00, 0x00, 0xFF).endVertex();
worldr.func_225582_a_(barLeft + barWidth, this.top, 0.0D).func_225583_a_(1.0F, 0.0F).func_225586_a_(0x00, 0x00, 0x00, 0xFF).endVertex();
worldr.func_225582_a_(barLeft, this.top, 0.0D).func_225583_a_(0.0F, 0.0F).func_225586_a_(0x00, 0x00, 0x00, 0xFF).endVertex();
tess.draw();
worldr.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
worldr.func_225582_a_(barLeft, barTop + barHeight, 0.0D).func_225583_a_(0.0F, 1.0F).func_225586_a_(0x80, 0x80, 0x80, 0xFF).endVertex();
worldr.func_225582_a_(barLeft + barWidth, barTop + barHeight, 0.0D).func_225583_a_(1.0F, 1.0F).func_225586_a_(0x80, 0x80, 0x80, 0xFF).endVertex();
worldr.func_225582_a_(barLeft + barWidth, barTop, 0.0D).func_225583_a_(1.0F, 0.0F).func_225586_a_(0x80, 0x80, 0x80, 0xFF).endVertex();
worldr.func_225582_a_(barLeft, barTop, 0.0D).func_225583_a_(0.0F, 0.0F).func_225586_a_(0x80, 0x80, 0x80, 0xFF).endVertex();
tess.draw();
worldr.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
worldr.func_225582_a_(barLeft, barTop + barHeight - 1, 0.0D).func_225583_a_(0.0F, 1.0F).func_225586_a_(0xC0, 0xC0, 0xC0, 0xFF).endVertex();
worldr.func_225582_a_(barLeft + barWidth - 1, barTop + barHeight - 1, 0.0D).func_225583_a_(1.0F, 1.0F).func_225586_a_(0xC0, 0xC0, 0xC0, 0xFF).endVertex();
worldr.func_225582_a_(barLeft + barWidth - 1, barTop, 0.0D).func_225583_a_(1.0F, 0.0F).func_225586_a_(0xC0, 0xC0, 0xC0, 0xFF).endVertex();
worldr.func_225582_a_(barLeft, barTop, 0.0D).func_225583_a_(0.0F, 0.0F).func_225586_a_(0xC0, 0xC0, 0xC0, 0xFF).endVertex();
tess.draw();
}
RenderSystem.enableTexture();
RenderSystem.shadeModel(GL11.GL_FLAT);
RenderSystem.enableAlphaTest();
RenderSystem.disableBlend();
GL11.glDisable(GL11.GL_SCISSOR_TEST);
}
protected void drawGradientRect(int left, int top, int right, int bottom, int color1, int color2)
{
GuiUtils.drawGradientRect(0, left, top, right, bottom, color1, color2);
}
@Override
public List<? extends IGuiEventListener> children()
{
return Collections.emptyList();
}
}