/* * Copyright (C) 2014 - 2020 | Alexander01998 | All rights reserved. * * This source code is subject to the terms of the GNU General Public * License, version 3. If a copy of the GPL was not distributed with this * file, You can obtain one at: https://www.gnu.org/licenses/gpl-3.0.txt */ package net.wurstclient.clickgui.components; import java.util.Arrays; import java.util.stream.IntStream; import java.util.stream.Stream; import org.lwjgl.opengl.GL11; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.util.math.MatrixStack; import net.wurstclient.WurstClient; import net.wurstclient.clickgui.ClickGui; import net.wurstclient.clickgui.ComboBoxPopup; import net.wurstclient.clickgui.Component; import net.wurstclient.clickgui.Window; import net.wurstclient.settings.EnumSetting; public final class ComboBoxComponent<T extends Enum<T>> extends Component { private final ClickGui gui = WurstClient.INSTANCE.getGui(); private final TextRenderer tr = WurstClient.MC.textRenderer; private final EnumSetting<T> setting; private final int popupWidth; private ComboBoxPopup<T> popup; public ComboBoxComponent(EnumSetting<T> setting) { this.setting = setting; popupWidth = calculatePopupWitdh(); setWidth(getDefaultWidth()); setHeight(getDefaultHeight()); } private int calculatePopupWitdh() { Stream<T> values = Arrays.stream(setting.getValues()); Stream<String> vNames = values.map(T::toString); IntStream vWidths = vNames.mapToInt(s -> tr.getWidth(s)); return vWidths.max().getAsInt(); } @Override public void handleMouseClick(double mouseX, double mouseY, int mouseButton) { if(mouseX < getX() + getWidth() - popupWidth - 15) return; switch(mouseButton) { case 0: handleLeftClick(); break; case 1: handleRightClick(); break; } } private void handleLeftClick() { if(isPopupOpen()) { popup.close(); popup = null; return; } popup = new ComboBoxPopup<>(this, setting, popupWidth); gui.addPopup(popup); } private void handleRightClick() { if(isPopupOpen()) return; T defaultSelected = setting.getDefaultSelected(); setting.setSelected(defaultSelected); } private boolean isPopupOpen() { return popup != null && !popup.isClosing(); } @Override public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { int x1 = getX(); int x2 = x1 + getWidth(); int x3 = x2 - 11; int x4 = x3 - popupWidth - 4; int y1 = getY(); int y2 = y1 + getHeight(); boolean hovering = isHovering(mouseX, mouseY, x1, x2, y1, y2); boolean hText = hovering && mouseX < x4; boolean hBox = hovering && mouseX >= x4; // tooltip if(hText) gui.setTooltip(setting.getDescription()); drawBackground(x1, x4, y1, y2); drawBox(x2, x4, y1, y2, hBox); drawSeparator(x3, y1, y2); drawArrow(x2, x3, y1, y2, hBox); drawNameAndValue(matrixStack, x1, x4, y1); } private boolean isHovering(int mouseX, int mouseY, int x1, int x2, int y1, int y2) { Window parent = getParent(); boolean scrollEnabled = parent.isScrollingEnabled(); int scroll = scrollEnabled ? parent.getScrollOffset() : 0; return mouseX >= x1 && mouseY >= y1 && mouseX < x2 && mouseY < y2 && mouseY >= -scroll && mouseY < parent.getHeight() - 13 - scroll; } private void drawBackground(int x1, int x4, int y1, int y2) { float[] bgColor = gui.getBgColor(); float opacity = gui.getOpacity(); GL11.glColor4f(bgColor[0], bgColor[1], bgColor[2], opacity); GL11.glBegin(GL11.GL_QUADS); GL11.glVertex2i(x1, y1); GL11.glVertex2i(x1, y2); GL11.glVertex2i(x4, y2); GL11.glVertex2i(x4, y1); GL11.glEnd(); } private void drawBox(int x2, int x4, int y1, int y2, boolean hBox) { float[] bgColor = gui.getBgColor(); float[] acColor = gui.getAcColor(); float opacity = gui.getOpacity(); // background float bgAlpha = hBox ? opacity * 1.5F : opacity; GL11.glColor4f(bgColor[0], bgColor[1], bgColor[2], bgAlpha); GL11.glBegin(GL11.GL_QUADS); GL11.glVertex2i(x4, y1); GL11.glVertex2i(x4, y2); GL11.glVertex2i(x2, y2); GL11.glVertex2i(x2, y1); GL11.glEnd(); // outline GL11.glColor4f(acColor[0], acColor[1], acColor[2], 0.5F); GL11.glBegin(GL11.GL_LINE_LOOP); GL11.glVertex2i(x4, y1); GL11.glVertex2i(x4, y2); GL11.glVertex2i(x2, y2); GL11.glVertex2i(x2, y1); GL11.glEnd(); } private void drawSeparator(int x3, int y1, int y2) { GL11.glBegin(GL11.GL_LINES); GL11.glVertex2i(x3, y1); GL11.glVertex2i(x3, y2); GL11.glEnd(); } private void drawArrow(int x2, int x3, int y1, int y2, boolean hBox) { double xa1 = x3 + 1; double xa2 = (x3 + x2) / 2.0; double xa3 = x2 - 1; double ya1; double ya2; if(isPopupOpen()) { ya1 = y2 - 3.5; ya2 = y1 + 3; GL11.glColor4f(hBox ? 1 : 0.85F, 0, 0, 1); }else { ya1 = y1 + 3.5; ya2 = y2 - 3; GL11.glColor4f(0, hBox ? 1 : 0.85F, 0, 1); } // arrow GL11.glBegin(GL11.GL_TRIANGLES); GL11.glVertex2d(xa1, ya1); GL11.glVertex2d(xa3, ya1); GL11.glVertex2d(xa2, ya2); GL11.glEnd(); // outline GL11.glColor4f(0.0625F, 0.0625F, 0.0625F, 0.5F); GL11.glBegin(GL11.GL_LINE_LOOP); GL11.glVertex2d(xa1, ya1); GL11.glVertex2d(xa3, ya1); GL11.glVertex2d(xa2, ya2); GL11.glEnd(); } private void drawNameAndValue(MatrixStack matrixStack, int x1, int x4, int y1) { GL11.glColor4f(1, 1, 1, 1); GL11.glEnable(GL11.GL_TEXTURE_2D); String name = setting.getName(); String value = "" + setting.getSelected(); int color = 0xF0F0F0; tr.draw(matrixStack, name, x1, y1 + 2, color); tr.draw(matrixStack, value, x4 + 2, y1 + 2, color); GL11.glDisable(GL11.GL_TEXTURE_2D); GL11.glEnable(GL11.GL_BLEND); } @Override public int getDefaultWidth() { return tr.getWidth(setting.getName()) + popupWidth + 17; } @Override public int getDefaultHeight() { return 11; } }