|
| 1 | +/* |
| 2 | + * Copyright (c) 2014-2025 Wurst-Imperium and contributors. |
| 3 | + * |
| 4 | + * This source code is subject to the terms of the GNU General Public |
| 5 | + * License, version 3. If a copy of the GPL was not distributed with this |
| 6 | + * file, You can obtain one at: https://www.gnu.org/licenses/gpl-3.0.txt |
| 7 | + */ |
| 8 | +package net.wurstclient.clickgui.components; |
| 9 | + |
| 10 | +import java.util.ArrayList; |
| 11 | + |
| 12 | +import org.lwjgl.glfw.GLFW; |
| 13 | + |
| 14 | +import net.minecraft.client.gui.GuiGraphics; |
| 15 | +import net.minecraft.client.input.MouseButtonEvent; |
| 16 | +import net.wurstclient.clickgui.ClickGuiIcons; |
| 17 | +import net.wurstclient.clickgui.ClickGui; |
| 18 | +import net.wurstclient.clickgui.Component; |
| 19 | +import net.wurstclient.settings.Setting; |
| 20 | +import net.wurstclient.settings.SettingGroup; |
| 21 | +import net.wurstclient.util.RenderUtils; |
| 22 | +import net.wurstclient.clickgui.Window; |
| 23 | + |
| 24 | +public final class SettingGroupComponent extends Component |
| 25 | +{ |
| 26 | + private static final int HEADER_HEIGHT = 13; |
| 27 | + private final SettingGroup group; |
| 28 | + private final ArrayList<Component> childComponents = new ArrayList<>(); |
| 29 | + private final boolean popoutEnabled; |
| 30 | + private boolean expanded; |
| 31 | + |
| 32 | + public SettingGroupComponent(SettingGroup group) |
| 33 | + { |
| 34 | + this(group, true); |
| 35 | + } |
| 36 | + |
| 37 | + public SettingGroupComponent(SettingGroup group, boolean allowPopout) |
| 38 | + { |
| 39 | + this.group = group; |
| 40 | + popoutEnabled = allowPopout && group.isPopout(); |
| 41 | + expanded = group.isDefaultExpanded(); |
| 42 | + rebuildChildren(); |
| 43 | + setWidth(getDefaultWidth()); |
| 44 | + setHeight(getDefaultHeight()); |
| 45 | + } |
| 46 | + |
| 47 | + private void rebuildChildren() |
| 48 | + { |
| 49 | + childComponents.clear(); |
| 50 | + for(Setting child : group.getChildren()) |
| 51 | + { |
| 52 | + Component comp = child.getComponent(); |
| 53 | + if(comp != null) |
| 54 | + { |
| 55 | + comp.setWidth(comp.getDefaultWidth()); |
| 56 | + comp.setHeight(comp.getDefaultHeight()); |
| 57 | + if(getParent() != null) |
| 58 | + comp.setParent(getParent()); |
| 59 | + childComponents.add(comp); |
| 60 | + } |
| 61 | + } |
| 62 | + updateHeight(); |
| 63 | + } |
| 64 | + |
| 65 | + private void updateHeight() |
| 66 | + { |
| 67 | + int height = HEADER_HEIGHT; |
| 68 | + if(expanded) |
| 69 | + for(Component child : childComponents) |
| 70 | + height += child.getHeight() + 2; |
| 71 | + setHeight(height); |
| 72 | + } |
| 73 | + |
| 74 | + private boolean togglePopoutWindow() |
| 75 | + { |
| 76 | + if(!popoutEnabled) |
| 77 | + return false; |
| 78 | + |
| 79 | + ClickGui gui = WURST.getGui(); |
| 80 | + Window existing = gui.findWindowByTitle(group.getName()); |
| 81 | + if(existing != null) |
| 82 | + { |
| 83 | + existing.close(); |
| 84 | + return true; |
| 85 | + } |
| 86 | + |
| 87 | + Window parent = getParent(); |
| 88 | + if(parent == null) |
| 89 | + return false; |
| 90 | + |
| 91 | + Window popupWin = new Window(group.getName()); |
| 92 | + for(Setting s : group.getChildren()) |
| 93 | + { |
| 94 | + Component c = s.getComponent(); |
| 95 | + if(c != null) |
| 96 | + { |
| 97 | + c.setWidth(c.getDefaultWidth()); |
| 98 | + c.setHeight(c.getDefaultHeight()); |
| 99 | + popupWin.add(c); |
| 100 | + } |
| 101 | + } |
| 102 | + popupWin.pack(); |
| 103 | + popupWin.setPinnable(true); |
| 104 | + popupWin.setClosable(true); |
| 105 | + popupWin.setX(parent.getX() + getX() + getWidth() + 5); |
| 106 | + popupWin.setY(parent.getY() + 13 + parent.getScrollOffset() + getY()); |
| 107 | + gui.addWindow(popupWin); |
| 108 | + return true; |
| 109 | + } |
| 110 | + |
| 111 | + @Override |
| 112 | + public void handleMouseClick(double mouseX, double mouseY, int mouseButton, |
| 113 | + MouseButtonEvent context) |
| 114 | + { |
| 115 | + if(mouseButton != GLFW.GLFW_MOUSE_BUTTON_LEFT) |
| 116 | + { |
| 117 | + if(expanded) |
| 118 | + for(Component child : childComponents) |
| 119 | + child.handleMouseClick(mouseX, mouseY, mouseButton, |
| 120 | + context); |
| 121 | + return; |
| 122 | + } |
| 123 | + |
| 124 | + int x1 = getX(); |
| 125 | + int y1 = getY(); |
| 126 | + int y2 = y1 + HEADER_HEIGHT; |
| 127 | + int x2 = x1 + getWidth(); |
| 128 | + int arrowX1 = x2 - 11; |
| 129 | + if(mouseX >= x1 && mouseX <= x1 + getWidth() && mouseY >= y1 |
| 130 | + && mouseY <= y2) |
| 131 | + { |
| 132 | + boolean clickedArrow = mouseX >= arrowX1 && mouseX <= x2 |
| 133 | + && mouseY >= y1 && mouseY <= y2; |
| 134 | + |
| 135 | + if(popoutEnabled && clickedArrow) |
| 136 | + { |
| 137 | + if(togglePopoutWindow()) |
| 138 | + return; |
| 139 | + } |
| 140 | + |
| 141 | + if(popoutEnabled) |
| 142 | + { |
| 143 | + if(togglePopoutWindow()) |
| 144 | + return; |
| 145 | + } |
| 146 | + |
| 147 | + expanded = !expanded; |
| 148 | + updateHeight(); |
| 149 | + return; |
| 150 | + } |
| 151 | + |
| 152 | + if(!expanded) |
| 153 | + return; |
| 154 | + |
| 155 | + for(Component child : childComponents) |
| 156 | + { |
| 157 | + int cx1 = child.getX(); |
| 158 | + int cy1 = child.getY(); |
| 159 | + int cx2 = cx1 + child.getWidth(); |
| 160 | + int cy2 = cy1 + child.getHeight(); |
| 161 | + |
| 162 | + if(mouseX < cx1 || mouseX > cx2 || mouseY < cy1 || mouseY > cy2) |
| 163 | + continue; |
| 164 | + |
| 165 | + child.handleMouseClick(mouseX, mouseY, mouseButton, context); |
| 166 | + break; |
| 167 | + } |
| 168 | + } |
| 169 | + |
| 170 | + @Override |
| 171 | + public void render(GuiGraphics context, int mouseX, int mouseY, |
| 172 | + float partialTicks) |
| 173 | + { |
| 174 | + int x1 = getX(); |
| 175 | + int y1 = getY(); |
| 176 | + int x2 = x1 + getWidth(); |
| 177 | + int y2 = y1 + HEADER_HEIGHT; |
| 178 | + |
| 179 | + boolean hoverHeader = |
| 180 | + mouseX >= x1 && mouseX <= x2 && mouseY >= y1 && mouseY <= y2; |
| 181 | + float opacity = WURST.getGui().getOpacity() * (hoverHeader ? 1.2F : 1F); |
| 182 | + int bgColor = |
| 183 | + RenderUtils.toIntColor(WURST.getGui().getBgColor(), opacity); |
| 184 | + context.fill(x1, y1, x2, y2, bgColor); |
| 185 | + |
| 186 | + int txtColor = WURST.getGui().getTxtColor(); |
| 187 | + context.drawString(MC.font, group.getName(), x1 + 4, y1 + 2, txtColor, |
| 188 | + false); |
| 189 | + ClickGuiIcons.drawMinimizeArrow(context, x2 - 11, y1 + 1, x2 - 1, |
| 190 | + y2 - 1, hoverHeader, !expanded); |
| 191 | + |
| 192 | + if(!expanded) |
| 193 | + return; |
| 194 | + |
| 195 | + int sectionTop = y2; |
| 196 | + int sectionBottom = sectionTop; |
| 197 | + for(Component child : childComponents) |
| 198 | + sectionBottom += child.getHeight() + 2; |
| 199 | + |
| 200 | + float sectionOpacity = popoutEnabled ? opacity * 0.9F : 1.0F; |
| 201 | + int sectionColor = |
| 202 | + RenderUtils.toIntColor(WURST.getGui().getBgColor(), sectionOpacity); |
| 203 | + context.fill(x1, sectionTop, x2, sectionBottom, sectionColor); |
| 204 | + |
| 205 | + int outlineColor = |
| 206 | + RenderUtils.toIntColor(WURST.getGui().getAcColor(), opacity * 0.5F); |
| 207 | + RenderUtils.drawLine2D(context, x1, sectionTop, x2, sectionTop, |
| 208 | + outlineColor); |
| 209 | + RenderUtils.drawLine2D(context, x1, sectionBottom, x2, sectionBottom, |
| 210 | + outlineColor); |
| 211 | + |
| 212 | + int childY = sectionTop + 1; |
| 213 | + for(Component child : childComponents) |
| 214 | + { |
| 215 | + child.setX(x1 + 2); |
| 216 | + child.setY(childY); |
| 217 | + child.setWidth(getWidth() - 4); |
| 218 | + |
| 219 | + child.render(context, mouseX, mouseY, partialTicks); |
| 220 | + childY += child.getHeight() + 2; |
| 221 | + } |
| 222 | + } |
| 223 | + |
| 224 | + @Override |
| 225 | + public void setParent(Window parent) |
| 226 | + { |
| 227 | + super.setParent(parent); |
| 228 | + for(Component child : childComponents) |
| 229 | + child.setParent(parent); |
| 230 | + } |
| 231 | + |
| 232 | + @Override |
| 233 | + public int getDefaultWidth() |
| 234 | + { |
| 235 | + return 200; |
| 236 | + } |
| 237 | + |
| 238 | + @Override |
| 239 | + public int getDefaultHeight() |
| 240 | + { |
| 241 | + return HEADER_HEIGHT; |
| 242 | + } |
| 243 | +} |
0 commit comments