1 package com.irtimaled.bbor.client.gui;
3 import com.irtimaled.bbor.client.renderers.Renderer;
4 import com.mojang.blaze3d.platform.GLX;
5 import net.minecraft.client.Minecraft;
6 import net.minecraft.client.gui.AbstractGui;
7 import net.minecraft.util.math.MathHelper;
8 import org.lwjgl.opengl.GL11;
10 import java.util.ArrayList;
11 import java.util.List;
13 public class ControlList extends AbstractGui implements IControlSet {
14 public static final int CONTROLS_WIDTH = 310;
15 protected static final int PADDING = 8;
17 protected final int listLeft;
18 protected final List<ControlListEntry> entries = new ArrayList<>();
19 private final int scrollBarLeft;
20 private final int listHeight;
21 private final Minecraft minecraft;
22 private final int width;
23 private final int height;
24 private final int top;
25 private final int bottom;
27 protected int contentHeight = PADDING;
28 private double amountScrolled;
29 private boolean clickedScrollbar;
30 private boolean transparentBackground;
31 private IControl focused;
32 private boolean isDragging;
34 ControlList(int width, int height, int top, int bottom) {
35 this.minecraft = Minecraft.getInstance();
37 this.scrollBarLeft = width - 6;
41 this.listHeight = bottom - top;
42 this.listLeft = width / 2 - CONTROLS_WIDTH / 2;
45 void add(ControlListEntry entry) {
46 entry.index = entries.size();
50 private void addEntry(ControlListEntry entry) {
51 this.entries.add(entry);
52 this.contentHeight += entry.getControlHeight();
55 public void filter(String lowerValue) {
58 for (ControlListEntry entry : entries) {
59 entry.filter(lowerValue);
60 if (entry.isVisible()) {
61 height += entry.getControlHeight();
62 } else if (entry == focused) {
66 this.contentHeight = height + PADDING;
70 this.entries.forEach(ControlListEntry::close);
74 public boolean mouseClicked(double mouseX, double mouseY, int button) {
75 this.clickedScrollbar = button == 0 && mouseX >= (double) this.scrollBarLeft;
76 return isMouseOver(mouseX, mouseY) &&
77 (IControlSet.super.mouseClicked(mouseX, mouseY, button) ||
78 this.clickedScrollbar);
82 public boolean isMouseOver(double mouseX, double mouseY) {
83 return mouseY >= (double) this.top && mouseY <= (double) this.bottom;
87 public boolean changeFocus(boolean moveForward) {
88 boolean newControlFocused = IControlSet.super.changeFocus(moveForward);
89 if (newControlFocused) {
90 this.ensureVisible((ControlListEntry) this.getFocused());
93 return newControlFocused;
96 private void ensureVisible(ControlListEntry control) {
97 int controlTop = control.getControlTop();
98 int controlHeight = control.getControlHeight();
99 int distanceAboveTop = this.top - controlTop;
100 if (distanceAboveTop > 0) {
101 this.amountScrolled -= Math.max(controlHeight, distanceAboveTop + PADDING);
105 int distanceBelowBottom = controlTop + controlHeight - this.bottom;
106 if (distanceBelowBottom > 0) {
107 this.amountScrolled += Math.max(controlHeight, distanceBelowBottom + PADDING);
112 public boolean mouseDragged(double mouseX, double mouseY, int button, double p_mouseDragged_6_, double p_mouseDragged_8_) {
113 if (IControlSet.super.mouseDragged(mouseX, mouseY, button, p_mouseDragged_6_, p_mouseDragged_8_)) {
116 if (button == 0 && this.clickedScrollbar) {
117 if (mouseY < (double) this.top) {
118 this.amountScrolled = 0.0D;
119 } else if (mouseY > (double) this.bottom) {
120 this.amountScrolled = this.getMaxScroll();
122 double maxScroll = this.getMaxScroll();
123 if (maxScroll < 1.0D) {
127 double amountScrolled = maxScroll / (double) (this.listHeight - getScrollBarHeight());
128 if (amountScrolled < 1.0D) {
129 amountScrolled = 1.0D;
132 this.amountScrolled += p_mouseDragged_8_ * amountScrolled;
140 private int getMaxScroll() {
141 return Math.max(0, this.contentHeight - (this.listHeight - 4));
144 private int getScrollBarHeight() {
145 return MathHelper.clamp((int) ((float) (this.listHeight * this.listHeight) / (float) this.contentHeight),
147 this.listHeight - PADDING);
151 public boolean mouseScrolled(double mouseX, double mouseY, double scrollAmount) {
152 this.amountScrolled -= scrollAmount * 10;
156 public void render(int mouseX, int mouseY) {
157 this.amountScrolled = MathHelper.clamp(this.amountScrolled, 0.0D, this.getMaxScroll());
159 GL11.glDisable(GL11.GL_LIGHTING);
160 GL11.glDisable(GL11.GL_FOG);
161 if (!transparentBackground) drawListBackground();
163 int listTop = this.top + PADDING - (int) this.amountScrolled;
165 drawEntries(mouseX, mouseY, listTop);
167 GL11.glDisable(GL11.GL_DEPTH_TEST);
168 this.overlayBackground(0, this.top);
169 this.overlayBackground(this.bottom, this.height);
170 GL11.glEnable(GL11.GL_BLEND);
171 GLX.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ZERO, GL11.GL_ONE);
172 GL11.glDisable(GL11.GL_ALPHA_TEST);
173 GL11.glShadeModel(GL11.GL_SMOOTH);
174 GL11.glDisable(GL11.GL_TEXTURE_2D);
175 drawOverlayShadows();
177 int maxScroll = this.getMaxScroll();
179 drawScrollBar(maxScroll);
182 GL11.glEnable(GL11.GL_TEXTURE_2D);
183 GL11.glShadeModel(GL11.GL_FLAT);
184 GL11.glEnable(GL11.GL_ALPHA_TEST);
185 GL11.glDisable(GL11.GL_BLEND);
188 private void drawListBackground() {
189 this.minecraft.getTextureManager().bindTexture(AbstractGui.BACKGROUND_LOCATION);
190 Renderer.startTextured()
191 .setColor(32, 32, 32)
193 .addPoint(0, this.bottom, 0.0D, (float) 0 / 32.0F, (float) (this.bottom + (int) this.amountScrolled) / 32.0F)
194 .addPoint(this.width, this.bottom, 0.0D, (float) this.width / 32.0F, (float) (this.bottom + (int) this.amountScrolled) / 32.0F)
195 .addPoint(this.width, this.top, 0.0D, (float) this.width / 32.0F, (float) (this.top + (int) this.amountScrolled) / 32.0F)
196 .addPoint(0, this.top, 0.0D, (float) 0 / 32.0F, (float) (this.top + (int) this.amountScrolled) / 32.0F)
200 private void drawEntries(int mouseX, int mouseY, int top) {
201 for (ControlListEntry entry : this.entries) {
202 if (!entry.isVisible()) continue;
204 entry.setX(this.listLeft);
207 int height = entry.getControlHeight();
208 drawEntry(mouseX, mouseY, top, entry, height);
213 protected void drawEntry(int mouseX, int mouseY, int top, ControlListEntry entry, int height) {
214 entry.render(mouseX, mouseY);
217 private void overlayBackground(int top, int bottom) {
218 this.minecraft.getTextureManager().bindTexture(AbstractGui.BACKGROUND_LOCATION);
219 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
220 Renderer.startTextured()
221 .setColor(64, 64, 64)
223 .addPoint(0, bottom, 0.0D, 0.0D, (float) bottom / 32.0F)
224 .addPoint(this.width, bottom, 0.0D, (float) this.width / 32.0F, (float) bottom / 32.0F)
225 .addPoint(this.width, top, 0.0D, (float) this.width / 32.0F, (float) top / 32.0F)
226 .addPoint(0, top, 0.0D, 0.0D, (float) top / 32.0F)
230 private void drawScrollBar(int maxScroll) {
231 int scrollBarHeight = this.getScrollBarHeight();
232 int scrollBarTop = (int) this.amountScrolled * (this.listHeight - scrollBarHeight) / maxScroll + this.top;
233 if (scrollBarTop < this.top) {
234 scrollBarTop = this.top;
237 Renderer.startTextured()
239 .addPoint(this.scrollBarLeft, this.bottom, 0.0D, 0.0D, 1.0D)
240 .addPoint(this.width, this.bottom, 0.0D, 1.0D, 1.0D)
241 .addPoint(this.width, this.top, 0.0D, 1.0D, 0.0D)
242 .addPoint(this.scrollBarLeft, this.top, 0.0D, 0.0D, 0.0D)
245 Renderer.startTextured()
246 .setColor(128, 128, 128)
248 .addPoint(this.scrollBarLeft, scrollBarTop + scrollBarHeight, 0.0D, 0.0D, 1.0D)
249 .addPoint(this.width, scrollBarTop + scrollBarHeight, 0.0D, 1.0D, 1.0D)
250 .addPoint(this.width, scrollBarTop, 0.0D, 1.0D, 0.0D)
251 .addPoint(this.scrollBarLeft, scrollBarTop, 0.0D, 0.0D, 0.0D)
254 Renderer.startTextured()
255 .setColor(192, 192, 192)
257 .addPoint(this.scrollBarLeft, scrollBarTop + scrollBarHeight - 1, 0.0D, 0.0D, 1.0D)
258 .addPoint(this.width - 1, scrollBarTop + scrollBarHeight - 1, 0.0D, 1.0D, 1.0D)
259 .addPoint(this.width - 1, scrollBarTop, 0.0D, 1.0D, 0.0D)
260 .addPoint(this.scrollBarLeft, scrollBarTop, 0.0D, 0.0D, 0.0D)
264 private void drawOverlayShadows() {
265 Renderer.startTextured()
266 .addPoint(0, this.top + 4, 0.0D, 0.0D, 1.0D)
267 .addPoint(this.width, this.top + 4, 0.0D, 1.0D, 1.0D)
269 .addPoint(this.width, this.top, 0.0D, 1.0D, 0.0D)
270 .addPoint(0, this.top, 0.0D, 0.0D, 0.0D)
272 Renderer.startTextured()
273 .addPoint(this.width, this.bottom - 4, 0.0D, 1.0D, 0.0D)
274 .addPoint(0, this.bottom - 4, 0.0D, 0.0D, 0.0D)
276 .addPoint(0, this.bottom, 0.0D, 0.0D, 1.0D)
277 .addPoint(this.width, this.bottom, 0.0D, 1.0D, 1.0D)
281 ControlList section(String title, CreateControl... createControls) {
282 this.add(new ControlListSection(title, createControls));
286 void setTransparentBackground() {
287 this.transparentBackground = true;
291 public List<? extends IControl> controls() {
296 public IControl getFocused() {
301 public void setFocused(IControl control) {
302 this.focused = control;
306 public boolean isDragging() {
311 public void setDragging(boolean dragging) {
312 this.isDragging = dragging;