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 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 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(); } }