petroleum/remappedSrc/pm/j4/petroleum/gui/PMovableButton.java

390 lines
13 KiB
Java

package pm.j4.petroleum.gui;
import com.mojang.blaze3d.systems.RenderSystem;
import java.util.List;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.LiteralText;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Matrix4f;
import pm.j4.petroleum.modules.menu.ModMenu;
import pm.j4.petroleum.util.data.ButtonInformation;
import pm.j4.petroleum.util.module.ModuleBase;
/**
* The type P movable button.
*/
public class PMovableButton extends AbstractButtonWidget {
/**
* The Expanded.
*/
private boolean expanded;
/**
* The Collapsed width.
*/
private final int collapsedWidth;
/**
* The Expanded width.
*/
private int expandedWidth;
/**
* The Collapsed height.
*/
private final int collapsedHeight;
/**
* The Expanded height.
*/
private int expandedHeight;
/**
* The Module height.
*/
private final int moduleHeight;
/**
* The Modules.
*/
private final List<ModuleBase> modules;
/**
* The Stored x.
*/
private int storedX;
/**
* The Stored y.
*/
private int storedY;
/**
* The Spin.
*/
private double spin;
/**
* The Arrow size.
*/
private final int arrowSize = 10;
/**
* The Category.
*/
private final String category;
/**
* The Parent.
*/
private final PModMenuScreen parent;
/**
* Instantiates a new P movable button.
*
* @param x the x
* @param y the y
* @param categoryName the category name
* @param modules the modules
* @param open the open
* @param parent the parent
*/
public PMovableButton(int x, int y, String categoryName, List<ModuleBase> modules, boolean open, PModMenuScreen parent) {
super(x, y, 0, 0, new TranslatableText(categoryName));
this.category = categoryName;
int w = MinecraftClient.getInstance().textRenderer.getWidth(new TranslatableText(categoryName)) + 8;
int h = MinecraftClient.getInstance().textRenderer.fontHeight + 8;
this.width = w;
this.collapsedWidth = w;
this.expandedWidth = 0;
this.height = h;
this.collapsedHeight = h;
this.expandedHeight = 0;
this.moduleHeight = h;
this.expanded = open;
this.modules = modules;
this.parent = parent;
}
@Override
public void onClick(double mouseX, double mouseY) {
this.storedX = (int) mouseX;
this.storedY = (int) mouseY;
super.onClick(mouseX, mouseY);
}
/**
* On extra click.
*
* @param mouseX the mouse x
* @param mouseY the mouse y
*/
private void onExtraClick(double mouseX, double mouseY) {
System.out.println("extra click");
int increment = this.moduleHeight + 4;
int location = (int)mouseY - (this.y + this.collapsedHeight);
int index = location / increment;
System.out.println("index: " + index);
if(modules.size() >= index) {
ModuleBase affectedModule = modules.get(index);
System.out.println("module: " + affectedModule);
if(affectedModule.isActivatable()) {
System.out.println("toggling");
affectedModule.toggle();
}
}
else {
System.out.println("index too great");
}
//TODO module things
}
@Override
public void onRelease(double mouseX, double mouseY) {
int mx = (int) mouseX;
int my = (int) mouseY;
/**
* The Padding.
*/
int padding = 5;
if (storedX + padding > mx && storedX - padding < mx &&
storedY + padding > my && storedY - padding < my) {
this.expanded = !this.expanded;
}
}
@Override
protected void onDrag(double mouseX, double mouseY, double deltaX, double deltaY) {
this.x += (int) deltaX;
this.y += (int) deltaY;
// i really hate to do it but nowhere else will it properly save
this.updateCoordinate();
}
/**
* Update coordinate.
*/
public void updateCoordinate() {
ModMenu.updateCoord(this.category, new ButtonInformation((this.x / (double) parent.width), (this.y / (double) parent.height), this.expanded));
}
// fuck click sounds
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (this.active && this.visible) {
if (this.isValidClickButton(button)) {
boolean bl = this.clicked(mouseX, mouseY);
if (bl && mouseY > this.y + this.collapsedHeight && mouseY < this.y + this.expandedHeight) {
this.onExtraClick(mouseX, mouseY);
return true;
} else if (bl) {
this.onClick(mouseX, mouseY);
return true;
}
}
}
return false;
}
/**
* Transition max width.
*
* @param width the width
*/
private void transitionMaxWidth(int width) {
double increment = ((width - this.width) / 20.0);
int sign = (width > this.width) ? 1 : -1;
if (increment == 0) {
this.width = width;
} else if (increment < 1 && increment > -1) {
this.width += sign;
} else {
this.width += (int) increment;
}
}
/**
* Transition max height.
*
* @param height the height
*/
private void transitionMaxHeight(int height) {
double increment = ((height - this.height) / 20.0);
int sign = (height > this.height) ? 1 : -1;
if (increment == 0) {
this.height = height;
} else if (increment < 1 && increment > -1) {
this.height += sign;
} else {
this.height += (int) increment;
}
}
@Override
public void renderButton(MatrixStack matrices, int mouseX, int mouseY, float delta) {
if (this.expandedWidth == 0 || this.expandedHeight == 0) {
this.expandedHeight = this.collapsedHeight + ((this.moduleHeight + 4) * modules.size());
modules.forEach(module -> {
this.expandedWidth = this.width;
int w = MinecraftClient.getInstance().textRenderer.getWidth(module.getReadableName()) + arrowSize + 8;
if (w > this.expandedWidth) {
this.expandedWidth = w;
}
});
// this should only run when opening the screen for the first time
if (this.expanded) {
this.height = expandedHeight;
this.width = expandedWidth;
}
}
MinecraftClient minecraftClient = MinecraftClient.getInstance();
TextRenderer textRenderer = minecraftClient.textRenderer;
minecraftClient.getTextureManager().bindTexture(WIDGETS_LOCATION);
RenderSystem.color4f(1.0F, 1.0F, 1.0F, this.alpha);
RenderSystem.disableTexture();
RenderSystem.defaultBlendFunc();
float brightness = this.isFocused() ? 1.0F : 0.5F;
RenderSystem.color4f(brightness, brightness, brightness, 1.0F);
Matrix4f matrix = matrices.peek().getModel();
int buttonLeft = this.x;
int buttonRight = this.x + width + 2;
int buttonTop = this.y;
int buttonBottom = this.y + this.collapsedHeight;
int buttonExpandedBottom = this.y + this.height;
Tessellator t_1 = Tessellator.getInstance();
BufferBuilder buffer = t_1.getBuffer();
RenderSystem.color4f(0.5F, 0.5F, 0.5F, 0.5F);
drawBox(t_1, buffer, matrix, buttonLeft, buttonRight, buttonTop - 2, buttonBottom + 2);
RenderSystem.color4f(0.0F, 0.0F, 0.0F, 0.3F);
drawBox(t_1, buffer, matrix, buttonLeft + 1, buttonRight - 1, buttonTop - 1, buttonBottom + 1);
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 0.9F);
drawEquilateralTriangle(t_1, buffer, matrix, 40, 40, 180, arrowSize);
drawEquilateralTriangle(t_1, buffer, matrix, 60, 60, 0, arrowSize);
drawEquilateralTriangle(t_1, buffer, matrix, 40, 60, 90, arrowSize);
drawEquilateralTriangle(t_1, buffer, matrix, 60, 40, 360, arrowSize);
drawEquilateralTriangle(t_1, buffer, matrix, 80, 40, 270, arrowSize);
drawEquilateralTriangle(t_1, buffer, matrix, 80, 60, 120, arrowSize);
int j = this.active ? 16777215 : 10526880;
if (this.expanded) {
if (this.width != this.expandedWidth || this.height != this.expandedHeight) {
transitionMaxWidth(this.expandedWidth);
transitionMaxHeight(this.expandedHeight);
RenderSystem.color4f(0.5F, 0.5F, 0.5F, 0.5F);
drawBox(t_1, buffer, matrix, buttonLeft, buttonRight, buttonBottom + 1, buttonExpandedBottom + 2);
RenderSystem.color4f(0.0F, 0.0F, 0.0F, 0.3F);
drawBox(t_1, buffer, matrix, buttonLeft + 1, buttonRight - 1, buttonBottom + 2, buttonExpandedBottom + 1);
if ((this.height - 8) / 2 > (this.collapsedHeight)) {
drawCenteredText(matrices, textRenderer, new LiteralText("..."), this.x + this.width / 2, this.y + (this.height - 8) / 2, j | MathHelper.ceil(this.alpha * 255.0F) << 24);
}
} else {
for (int i = 0; i < modules.size(); i++) {
int adjustedIndex = i + 1;
int previousBottom = buttonBottom + (i * (this.moduleHeight + 4));
int currentBottom = buttonBottom + ((i + 1) * (this.moduleHeight + 4));
RenderSystem.defaultBlendFunc();
RenderSystem.color4f(0.5F, 0.5F, 0.5F, 0.5F);
drawBox(t_1, buffer, matrix, buttonLeft, buttonRight, previousBottom + 1, currentBottom + 2);
RenderSystem.color4f(0.0F, 0.0F, 0.0F, 0.3F);
drawBox(t_1, buffer, matrix, buttonLeft + 1, buttonRight - 1, previousBottom + 2, currentBottom + 1);
drawCenteredText(matrices,
textRenderer,
modules.get(i).getReadableName(),
this.x + this.width / 2,
this.y + ((this.collapsedHeight - 8) / 2 + ((moduleHeight + 4) * adjustedIndex)),
j | MathHelper.ceil(this.alpha * 255.0F) << 24);
}
}
} else {
if (this.width != this.collapsedWidth || this.height != this.collapsedHeight) {
transitionMaxWidth(this.collapsedWidth);
transitionMaxHeight(this.collapsedHeight);
RenderSystem.color4f(0.5F, 0.5F, 0.5F, 0.5F);
drawBox(t_1, buffer, matrix, buttonLeft, buttonRight, buttonBottom + 1, buttonExpandedBottom + 2);
RenderSystem.color4f(0.0F, 0.0F, 0.0F, 0.3F);
drawBox(t_1, buffer, matrix, buttonLeft + 1, buttonRight - 1, buttonBottom + 2, buttonExpandedBottom + 1);
if ((this.height - 8) / 2 > (this.collapsedHeight)) {
drawCenteredText(matrices, textRenderer, new LiteralText("..."), this.x + this.width / 2, this.y + (this.height - 8) / 2, j | MathHelper.ceil(this.alpha * 255.0F) << 24);
}
}
}
RenderSystem.enableTexture();
drawCenteredText(matrices, textRenderer, this.getMessage(), this.x + this.width / 2, this.y + (this.collapsedHeight - 8) / 2, j | MathHelper.ceil(this.alpha * 255.0F) << 24);
}
/**
* Draw equilateral triangle.
*
* @param t_1 the t 1
* @param buffer the buffer
* @param matrix the matrix
* @param centerX the center x
* @param centerY the center y
* @param rotation the rotation
* @param distance the distance
*/
private void drawEquilateralTriangle(Tessellator t_1, BufferBuilder buffer, Matrix4f matrix, int centerX, int centerY, double rotation, int distance) {
double rotation1 = rotation;
double rotation2 = rotation + 120;
double rotation3 = rotation + 240;
int point1X = (int)(distance * Math.cos(Math.toRadians(rotation1))) + centerX;
int point1Y = (int)(distance * Math.sin(Math.toRadians(rotation1))) + centerY;
int point2X = (int)(distance * Math.cos(Math.toRadians(rotation2))) + centerX;
int point2Y = (int)(distance * Math.sin(Math.toRadians(rotation2))) + centerY;
int point3X = (int)(distance * Math.cos(Math.toRadians(rotation3))) + centerX;
int point3Y = (int)(distance * Math.sin(Math.toRadians(rotation3))) + centerY;
//RenderSystem.enableBlend();
RenderSystem.disableBlend();
buffer.begin(7, VertexFormats.POSITION_COLOR);
buffer.vertex(matrix, centerX, centerY, 0.0F).color(0.0F, 1.0F, 1.0F, 1.0F).next();
buffer.vertex(matrix, centerX, point1Y, 0.0F).color(0.0F, 1.0F, 1.0F, 1.0F).next();
buffer.vertex(matrix, point1X, point1Y, 0.0F).color(0.0F, 1.0F, 1.0F, 1.0F).next();
buffer.vertex(matrix, centerX, centerY, 0.0F).color(0.5F, 1.0F, 1.0F, 1.0F).next();
buffer.vertex(matrix, centerX, point2Y, 0.0F).color(0.5F, 1.0F, 1.0F, 1.0F).next();
buffer.vertex(matrix, point2X, point2Y, 0.0F).color(0.5F, 1.0F, 1.0F, 1.0F).next();
buffer.vertex(matrix, centerX, centerY, 0.0F).color(1.0F, 0.0F, 1.0F, 1.0F).next();
buffer.vertex(matrix, centerX, point3Y, 0.0F).color(1.0F, 0.0F, 1.0F, 1.0F).next();
buffer.vertex(matrix, point3X, point3Y, 0.0F).color(1.0F, 0.0F, 1.0F, 1.0F).next();
t_1.draw();
}
/**
* Draw box.
*
* @param t_1 the t 1
* @param buffer the buffer
* @param matrix the matrix
* @param buttonLeft the button left
* @param buttonRight the button right
* @param buttonTop the button top
* @param buttonBottom the button bottom
*/
private void drawBox(Tessellator t_1, BufferBuilder buffer, Matrix4f matrix, int buttonLeft, int buttonRight, int buttonTop, int buttonBottom) {
RenderSystem.enableBlend();
buffer.begin(7, VertexFormats.POSITION);
buffer.vertex(matrix, buttonLeft, buttonBottom, 0.0F).next();
buffer.vertex(matrix, buttonRight, buttonBottom, 0.0F).next();
buffer.vertex(matrix, buttonRight, buttonTop, 0.0F).next();
buffer.vertex(matrix, buttonLeft, buttonTop, 0.0F).next();
t_1.draw();
}
}