1 package com.irtimaled.bbor.client.gui;
3 import com.irtimaled.bbor.client.renderers.Renderer;
4 import net.minecraft.client.Minecraft;
5 import net.minecraft.client.gui.Gui;
6 import net.minecraft.client.gui.GuiEventHandler;
7 import net.minecraft.client.gui.IGuiEventListener;
8 import net.minecraft.client.renderer.OpenGlHelper;
9 import net.minecraft.util.math.MathHelper;
10 import org.lwjgl.opengl.GL11;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.List;
16 public class ControlList extends GuiEventHandler {
17 private static final int CONTROLS_WIDTH = 310;
18 private final int scrollBarLeft;
19 private final int listHeight;
20 private final int listLeft;
21 private final int listRight;
22 private final Minecraft minecraft;
23 private final List<ControlListEntry> entries = new ArrayList<>();
24 private final int width;
25 private final int height;
26 private final int top;
27 private final int bottom;
29 private int contentHeight = 8;
30 private int selectedElement;
31 private double amountScrolled;
32 private boolean clickedScrollbar;
33 private boolean showSelectionBox;
34 private boolean transparentBackground;
36 ControlList(int width, int height, int top, int bottom) {
37 this.minecraft = Minecraft.getInstance();
39 this.scrollBarLeft = width - 6;
43 this.listHeight = bottom - top;
44 this.listLeft = width / 2 - CONTROLS_WIDTH / 2;
45 this.listRight = this.listLeft + CONTROLS_WIDTH;
46 this.selectedElement = -1;
49 void add(ControlListEntry entry) {
51 entry.index = entries.size();
55 private void addEntry(ControlListEntry entry) {
56 this.entries.add(entry);
57 this.contentHeight += entry.getControlHeight();
60 ControlListEntry getSelectedEntry() {
61 return this.selectedElement >= 0 && this.selectedElement < this.entries.size() ? this.entries.get(this.selectedElement) : null;
64 void filter(String lowerValue) {
66 for (IControl entry : entries) {
67 entry.filter(lowerValue);
68 if (entry.getVisible())
69 height += entry.getControlHeight();
71 this.contentHeight = height + 8;
75 this.entries.forEach(ControlListEntry::close);
79 public boolean mouseClicked(double mouseX, double mouseY, int button) {
80 this.clickedScrollbar = button == 0 && mouseX >= (double) this.scrollBarLeft;
81 if (mouseY >= (double) this.top && mouseY <= (double) this.bottom) {
82 ControlListEntry entry = this.getEntryAt(mouseX, mouseY);
83 if (entry != null && entry.mouseClicked(mouseX, mouseY, button)) {
84 this.setDragging(true);
85 this.setSelectedIndex(entry.index);
88 return this.clickedScrollbar;
95 void setSelectedIndex(int index) {
96 this.selectedElement = index;
99 private ControlListEntry getEntryAt(double mouseX, double mouseY) {
100 if (mouseX >= listLeft && mouseX <= listRight) {
101 for (ControlListEntry entry : entries) {
102 if (!entry.getVisible()) continue;
104 int top = entry.getY();
105 int bottom = top + entry.getControlHeight();
106 if (mouseY >= top && mouseY <= bottom)
114 public boolean mouseDragged(double mouseX, double mouseY, int button, double p_mouseDragged_6_, double p_mouseDragged_8_) {
115 if (super.mouseDragged(mouseX, mouseY, button, p_mouseDragged_6_, p_mouseDragged_8_)) {
117 } else if (button == 0 && this.clickedScrollbar) {
118 if (mouseY < (double) this.top) {
119 this.amountScrolled = 0.0D;
120 } else if (mouseY > (double) this.bottom) {
121 this.amountScrolled = this.getMaxScroll();
123 double maxScroll = this.getMaxScroll();
124 if (maxScroll < 1.0D) {
128 double amountScrolled = maxScroll / (double) (this.listHeight - getScrollBarHeight());
129 if (amountScrolled < 1.0D) {
130 amountScrolled = 1.0D;
133 this.amountScrolled += p_mouseDragged_8_ * amountScrolled;
142 private int getMaxScroll() {
143 return Math.max(0, this.contentHeight - (this.listHeight - 4));
146 private int getScrollBarHeight() {
147 return MathHelper.clamp((int) ((float) (this.listHeight * this.listHeight) / (float) this.contentHeight),
149 this.listHeight - 8);
153 public boolean mouseReleased(double mouseX, double mouseY, int button) {
154 this.entries.forEach(entry -> entry.mouseReleased(mouseX, mouseY, button));
159 public boolean mouseScrolled(double scrollAmount) {
160 this.amountScrolled -= scrollAmount * 10;
164 public void render(int mouseX, int mouseY) {
165 this.amountScrolled = MathHelper.clamp(this.amountScrolled, 0.0D, this.getMaxScroll());
167 GL11.glDisable(GL11.GL_LIGHTING);
168 GL11.glDisable(GL11.GL_FOG);
169 if (!transparentBackground) drawListBackground();
171 int listTop = this.top + 8 - (int) this.amountScrolled;
173 drawEntries(mouseX, mouseY, listTop);
175 GL11.glDisable(GL11.GL_DEPTH_TEST);
176 this.overlayBackground(0, this.top);
177 this.overlayBackground(this.bottom, this.height);
178 GL11.glEnable(GL11.GL_BLEND);
179 OpenGlHelper.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ZERO, GL11.GL_ONE);
180 GL11.glDisable(GL11.GL_ALPHA_TEST);
181 GL11.glShadeModel(GL11.GL_SMOOTH);
182 GL11.glDisable(GL11.GL_TEXTURE_2D);
183 drawOverlayShadows();
185 int maxScroll = this.getMaxScroll();
187 drawScrollBar(maxScroll);
190 GL11.glEnable(GL11.GL_TEXTURE_2D);
191 GL11.glShadeModel(GL11.GL_FLAT);
192 GL11.glEnable(GL11.GL_ALPHA_TEST);
193 GL11.glDisable(GL11.GL_BLEND);
196 private void drawListBackground() {
197 this.minecraft.getTextureManager().bindTexture(Gui.OPTIONS_BACKGROUND);
198 Renderer.startTextured()
199 .setColor(32, 32, 32)
201 .addPoint(0, this.bottom, 0.0D, (float) 0 / 32.0F, (float) (this.bottom + (int) this.amountScrolled) / 32.0F)
202 .addPoint(this.width, this.bottom, 0.0D, (float) this.width / 32.0F, (float) (this.bottom + (int) this.amountScrolled) / 32.0F)
203 .addPoint(this.width, this.top, 0.0D, (float) this.width / 32.0F, (float) (this.top + (int) this.amountScrolled) / 32.0F)
204 .addPoint(0, this.top, 0.0D, (float) 0 / 32.0F, (float) (this.top + (int) this.amountScrolled) / 32.0F)
208 private void drawEntries(int mouseX, int mouseY, int top) {
209 for (ControlListEntry entry : this.entries) {
210 if (!entry.getVisible()) continue;
212 entry.setX(this.listLeft);
215 int height = entry.getControlHeight();
217 if (this.showSelectionBox && this.selectedElement == entry.index) {
218 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
219 GL11.glDisable(GL11.GL_TEXTURE_2D);
220 Renderer.startTextured()
222 .setColor(128, 128, 128)
223 .addPoint((double) this.listLeft - 2, (double) (top + height) - 2, 0.0D, 0.0D, 1.0D)
224 .addPoint((double) this.listRight + 2, (double) (top + height) - 2, 0.0D, 1.0D, 1.0D)
225 .addPoint((double) this.listRight + 2, top - 2, 0.0D, 1.0D, 0.0D)
226 .addPoint((double) this.listLeft - 2, top - 2, 0.0D, 0.0D, 0.0D)
228 .addPoint(this.listLeft - 1, (double) (top + height) - 3, 0.0D, 0.0D, 1.0D)
229 .addPoint(this.listRight + 1, (double) (top + height) - 3, 0.0D, 1.0D, 1.0D)
230 .addPoint(this.listRight + 1, top - 1, 0.0D, 1.0D, 0.0D)
231 .addPoint(this.listLeft - 1, top - 1, 0.0D, 0.0D, 0.0D)
233 GL11.glEnable(GL11.GL_TEXTURE_2D);
236 entry.render(mouseX, mouseY);
237 top += entry.getControlHeight();
241 private void overlayBackground(int top, int bottom) {
242 this.minecraft.getTextureManager().bindTexture(Gui.OPTIONS_BACKGROUND);
243 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
244 Renderer.startTextured()
245 .setColor(64, 64, 64)
247 .addPoint(0, bottom, 0.0D, 0.0D, (float) bottom / 32.0F)
248 .addPoint(this.width, bottom, 0.0D, (float) this.width / 32.0F, (float) bottom / 32.0F)
249 .addPoint(this.width, top, 0.0D, (float) this.width / 32.0F, (float) top / 32.0F)
250 .addPoint(0, top, 0.0D, 0.0D, (float) top / 32.0F)
254 private void drawScrollBar(int maxScroll) {
255 int scrollBarHeight = this.getScrollBarHeight();
256 int scrollBarTop = (int) this.amountScrolled * (this.listHeight - scrollBarHeight) / maxScroll + this.top;
257 if (scrollBarTop < this.top) {
258 scrollBarTop = this.top;
261 Renderer.startTextured()
263 .addPoint(this.scrollBarLeft, this.bottom, 0.0D, 0.0D, 1.0D)
264 .addPoint(this.width, this.bottom, 0.0D, 1.0D, 1.0D)
265 .addPoint(this.width, this.top, 0.0D, 1.0D, 0.0D)
266 .addPoint(this.scrollBarLeft, this.top, 0.0D, 0.0D, 0.0D)
269 Renderer.startTextured()
270 .setColor(128, 128, 128)
272 .addPoint(this.scrollBarLeft, scrollBarTop + scrollBarHeight, 0.0D, 0.0D, 1.0D)
273 .addPoint(this.width, scrollBarTop + scrollBarHeight, 0.0D, 1.0D, 1.0D)
274 .addPoint(this.width, scrollBarTop, 0.0D, 1.0D, 0.0D)
275 .addPoint(this.scrollBarLeft, scrollBarTop, 0.0D, 0.0D, 0.0D)
278 Renderer.startTextured()
279 .setColor(192, 192, 192)
281 .addPoint(this.scrollBarLeft, scrollBarTop + scrollBarHeight - 1, 0.0D, 0.0D, 1.0D)
282 .addPoint(this.width - 1, scrollBarTop + scrollBarHeight - 1, 0.0D, 1.0D, 1.0D)
283 .addPoint(this.width - 1, scrollBarTop, 0.0D, 1.0D, 0.0D)
284 .addPoint(this.scrollBarLeft, scrollBarTop, 0.0D, 0.0D, 0.0D)
288 private void drawOverlayShadows() {
289 Renderer.startTextured()
290 .addPoint(0, this.top + 4, 0.0D, 0.0D, 1.0D)
291 .addPoint(this.width, this.top + 4, 0.0D, 1.0D, 1.0D)
293 .addPoint(this.width, this.top, 0.0D, 1.0D, 0.0D)
294 .addPoint(0, this.top, 0.0D, 0.0D, 0.0D)
296 Renderer.startTextured()
297 .addPoint(this.width, this.bottom - 4, 0.0D, 1.0D, 0.0D)
298 .addPoint(0, this.bottom - 4, 0.0D, 0.0D, 0.0D)
300 .addPoint(0, this.bottom, 0.0D, 0.0D, 1.0D)
301 .addPoint(this.width, this.bottom, 0.0D, 1.0D, 1.0D)
306 protected List<? extends IGuiEventListener> getChildren() {
307 return Collections.emptyList();
310 ControlList section(String title, CreateControl... createControls) {
311 this.add(new ControlListSection(title, createControls));
315 void showSelectionBox() {
316 this.showSelectionBox = true;
319 void setTransparentBackground() {
320 this.transparentBackground = true;