/* * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod * Copyright (C) 2021 cyoung06 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ package kr.syeyoung.dungeonsguide.gui; import kr.syeyoung.dungeonsguide.gui.elements.MTooltip; import kr.syeyoung.dungeonsguide.utils.cursor.EnumCursor; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.renderer.GlStateManager; import org.lwjgl.opengl.GL11; import java.awt.*; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @Getter public class MPanel { protected Rectangle bounds = new Rectangle(0,0,0,0); // relative to parent protected List childComponents = new CopyOnWriteArrayList(); protected Color backgroundColor = new Color(0,0,0,0); protected Rectangle lastAbsClip = new Rectangle(0,0,0,0); @Getter(AccessLevel.PUBLIC) @Setter protected boolean isFocused; @Getter @Setter protected MPanel parent; private boolean debug; public void setBackgroundColor(Color c) { if (c == null) return; this.backgroundColor = c; } public void setPosition(Point pt) { this.setBounds(new Rectangle(pt.x, pt.y, getBounds().width, getBounds().height)); } public void setSize(Dimension dim) { this.setBounds(new Rectangle(getBounds().x, getBounds().y, dim.width, dim.height)); } public Dimension getSize() { return getBounds().getSize(); } public Dimension getPreferredSize() { return getSize(); } public void setBounds(Rectangle bounds) { if (bounds == null) return; this.bounds.x = bounds.x; this.bounds.y = bounds.y; this.bounds.width = bounds.width; this.bounds.height = bounds.height; for (MPanel childComponent : childComponents) { childComponent.resize0(getBounds().width, getBounds().height); } onBoundsUpdate(); } public void onBoundsUpdate() { } public void add(MPanel child) { if (child.parent != null) throw new IllegalArgumentException("What have you done"); this.childComponents.add(child); child.setParent(this); } public void openTooltip(MTooltip mPanel) { parent.openTooltip(mPanel); } public int getTooltipsOpen() { return parent.getTooltipsOpen(); } public void remove(MPanel panel) { if (panel != null) panel.setParent(null); this.childComponents.remove(panel); } protected Point lastParentPoint; @Getter @Setter private boolean ignoreBoundOnClip; public void render0(double scale, Point parentPoint, Rectangle parentClip, int absMousex, int absMousey, int relMousex0, int relMousey0, float partialTicks) { // 0,0 - a a lastParentPoint = parentPoint; int relMousex = relMousex0 - getBounds().x; int relMousey = relMousey0 - getBounds().y; GlStateManager.translate(getBounds().x, getBounds().y, 5); GlStateManager.color(1,1,1,1); Rectangle absBound = getBounds().getBounds(); absBound.setLocation(absBound.x + parentPoint.x, absBound.y + parentPoint.y); Rectangle clip; if (ignoreBoundOnClip) clip = parentClip; else clip = determineClip(parentClip, absBound); lastAbsClip = clip; if (clip.getSize().height * clip.getSize().width == 0) return; this.scale = scale; clip(clip.x, clip.y, clip.width, clip.height); GL11.glEnable(GL11.GL_SCISSOR_TEST); GuiScreen.drawRect(0,0, getBounds().width, getBounds().height, backgroundColor.getRGB()); GlStateManager.enableBlend(); GlStateManager.pushMatrix(); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); GlStateManager.enableBlend(); GlStateManager.enableAlpha(); GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); render(absMousex, absMousey, relMousex, relMousey, partialTicks, clip); GlStateManager.popMatrix(); if (debug && lastAbsClip.contains(absMousex, absMousey)) { GL11.glDisable(GL11.GL_SCISSOR_TEST); Gui.drawRect(0, 0, getBounds().width, getBounds().height, 0x2200FF00); Gui.drawRect(0, 0, getPreferredSize().width, getPreferredSize().height, 0x220000FF); } GL11.glDisable(GL11.GL_SCISSOR_TEST); Point newPt = new Point(parentPoint.x + getBounds().x, parentPoint.y + getBounds().y); for (MPanel mPanel : getChildComponents()){ GlStateManager.pushMatrix(); mPanel.render0(scale, newPt, clip, absMousex, absMousey, relMousex, relMousey, partialTicks); GlStateManager.popMatrix(); } } protected double scale; public void clip(int x, int y, int width, int height) { if (width < 0 || height < 0) return; GL11.glScissor((int) (x * scale), Minecraft.getMinecraft().displayHeight - (int) ((y + height) * scale), (int)(width* scale + scale) - 1, (int) (height * scale + scale) - 1); } protected Rectangle determineClip(Rectangle rect1, Rectangle rect2) { int minX = Math.max(rect1.x, rect2.x); int minY = Math.max(rect1.y, rect2.y); int maxX = Math.min(rect1.x + rect1.width, rect2.x + rect2.width); int maxY = Math.min(rect1.y + rect1.height, rect2.y +rect2.height); if (minX > maxX) return new Rectangle(0,0,0,0); if (minY > maxY) return new Rectangle(0,0,0,0); return new Rectangle(minX, minY, maxX - minX, maxY - minY); } public void render(int absMousex, int absMousey, int relMousex0, int relMousey0, float partialTicks, Rectangle scissor) {} public void resize0(int parentWidth, int parentHeight) { resize(parentWidth, parentHeight); } public void resize(int parentWidth, int parentHeight) {} public void keyPressed0(char typedChar, int keyCode) { for (MPanel childComponent : getChildComponents()) { childComponent.keyPressed0(typedChar, keyCode); } if (isFocused) keyPressed(typedChar, keyCode); } public void keyPressed(char typedChar, int keyCode) {} public void keyHeld0(char typedChar, int keyCode, long heldMS) { for (MPanel childComponent : getChildComponents()) { childComponent.keyHeld0(typedChar, keyCode, heldMS); } if (isFocused) keyHeld(typedChar, keyCode, heldMS); } public void keyHeld(char typedChar, int keyCode, long heldMS) {} public void keyReleased0(char typedChar, int keyCode, long heldMS) { for (MPanel childComponent : getChildComponents()) { childComponent.keyReleased0(typedChar, keyCode, heldMS); } if (isFocused) keyReleased(typedChar, keyCode, heldMS); } public void keyReleased(char typedChar, int keyCode, long heldMS) {} public boolean mouseClicked0(int absMouseX, int absMouseY, int relMouseX0, int relMouseY0, int mouseButton) { int relMousex = relMouseX0 - getBounds().x; int relMousey = relMouseY0 - getBounds().y; boolean noClip = true; boolean focusedOverall = false; for (MPanel childComponent : getChildComponents()) { if (childComponent.mouseClicked0(absMouseX, absMouseY, relMousex, relMousey, mouseButton)) { noClip = false; focusedOverall = true; } } if (getBounds().contains(relMouseX0, relMouseY0) && noClip) { isFocused = true; focusedOverall = true; } else { isFocused = false; } mouseClicked(absMouseX, absMouseY, relMousex, relMousey, mouseButton); return focusedOverall; } public void mouseClicked(int absMouseX, int absMouseY, int relMouseX, int relMouseY, int mouseButton) {} public void mouseReleased0(int absMouseX, int absMouseY, int relMouseX0, int relMouseY0, int state) { int relMousex = relMouseX0 - getBounds().x; int relMousey = relMouseY0 - getBounds().y; for (MPanel childComponent : getChildComponents()) { childComponent.mouseReleased0(absMouseX, absMouseY, relMousex, relMousey, state); } mouseReleased(absMouseX, absMouseY, relMousex, relMousey, state); } public void mouseReleased(int absMouseX, int absMouseY, int relMouseX, int relMouseY, int state) {} public void mouseClickMove0(int absMouseX, int absMouseY, int relMouseX0, int relMouseY0, int clickedMouseButton, long timeSinceLastClick) { int relMousex = relMouseX0 - getBounds().x; int relMousey = relMouseY0 - getBounds().y; for (MPanel childComponent : getChildComponents()) { childComponent.mouseClickMove0(absMouseX, absMouseY, relMousex, relMousey, clickedMouseButton, timeSinceLastClick); } mouseClickMove(absMouseX, absMouseY, relMousex, relMousey, clickedMouseButton, timeSinceLastClick); } public void mouseClickMove(int absMouseX, int absMouseY, int relMouseX, int relMouseY, int clickedMouseButton, long timeSinceLastClick) {} public void mouseScrolled0(int absMouseX, int absMouseY, int relMouseX0, int relMouseY0, int scrollAmount) { int relMousex = relMouseX0 - getBounds().x; int relMousey = relMouseY0 - getBounds().y; for (MPanel childComponent : getChildComponents()) { childComponent.mouseScrolled0(absMouseX, absMouseY, relMousex, relMousey, scrollAmount); } mouseScrolled(absMouseX, absMouseY, relMousex, relMousey, scrollAmount); } public void mouseScrolled(int absMouseX, int absMouseY, int relMouseX0, int relMouseY0, int scrollAmount) {} public void mouseMoved0(int absMouseX, int absMouseY, int relMouseX0, int relMouseY0) { int relMousex = relMouseX0 - getBounds().x; int relMousey = relMouseY0 - getBounds().y; mouseMoved(absMouseX, absMouseY, relMousex, relMousey); for (MPanel childComponent : getChildComponents()) { childComponent.mouseMoved0(absMouseX, absMouseY, relMousex, relMousey); } } public void mouseMoved(int absMouseX, int absMouseY, int relMouseX0, int relMouseY0) {} public void setCursor(EnumCursor enumCursor) { parent.setCursor(enumCursor); } }