1 package com.irtimaled.bbor.client.gui;
3 import com.irtimaled.bbor.client.renderers.RenderHelper;
4 import com.irtimaled.bbor.client.renderers.Renderer;
5 import com.irtimaled.bbor.common.MathHelper;
6 import net.minecraft.client.gui.DrawableHelper;
7 import net.minecraft.client.util.math.MatrixStack;
9 import java.util.ArrayList;
10 import java.util.List;
12 public class ControlList extends DrawableHelper implements IControlSet {
13 public static final int CONTROLS_WIDTH = 310;
14 protected static final int PADDING = 8;
16 protected final int listLeft;
17 protected final List<ControlListEntry> entries = new ArrayList<>();
18 private final int scrollBarLeft;
19 private final int listHeight;
20 private final int width;
21 private final int height;
22 private final int top;
23 private final int bottom;
25 protected int contentHeight = PADDING;
26 private double amountScrolled;
27 private boolean clickedScrollbar;
28 private boolean transparentBackground;
29 private IControl focused;
30 private boolean isDragging;
32 ControlList(int width, int height, int top, int bottom) {
34 this.scrollBarLeft = width - 6;
38 this.listHeight = bottom - top;
39 this.listLeft = width / 2 - CONTROLS_WIDTH / 2;
42 void add(ControlListEntry entry) {
43 entry.index = entries.size();
47 private void addEntry(ControlListEntry entry) {
48 this.entries.add(entry);
49 this.contentHeight += entry.getControlHeight();
52 public void filter(String lowerValue) {
55 for (ControlListEntry entry : entries) {
56 entry.filter(lowerValue);
57 if (entry.isVisible()) {
58 height += entry.getControlHeight();
59 } else if (entry == focused) {
63 this.contentHeight = height + PADDING;
67 this.entries.forEach(ControlListEntry::close);
71 public boolean mouseClicked(double mouseX, double mouseY, int button) {
72 this.clickedScrollbar = button == 0 && mouseX >= (double) this.scrollBarLeft;
73 return isMouseOver(mouseX, mouseY) &&
74 (IControlSet.super.mouseClicked(mouseX, mouseY, button) ||
75 this.clickedScrollbar);
79 public boolean isMouseOver(double mouseX, double mouseY) {
80 return mouseY >= (double) this.top && mouseY <= (double) this.bottom;
84 public boolean changeFocus(boolean moveForward) {
85 boolean newControlFocused = IControlSet.super.changeFocus(moveForward);
86 if (newControlFocused) {
87 this.ensureVisible((ControlListEntry) this.getFocused());
90 return newControlFocused;
93 private void ensureVisible(ControlListEntry control) {
94 int controlTop = control.getControlTop();
95 int controlHeight = control.getControlHeight();
96 int distanceAboveTop = this.top - controlTop;
97 if (distanceAboveTop > 0) {
98 this.amountScrolled -= Math.max(controlHeight, distanceAboveTop + PADDING);
102 int distanceBelowBottom = controlTop + controlHeight - this.bottom;
103 if (distanceBelowBottom > 0) {
104 this.amountScrolled += Math.max(controlHeight, distanceBelowBottom + PADDING);
109 public boolean mouseDragged(double mouseX, double mouseY, int button, double p_mouseDragged_6_, double p_mouseDragged_8_) {
110 if (IControlSet.super.mouseDragged(mouseX, mouseY, button, p_mouseDragged_6_, p_mouseDragged_8_)) {
113 if (button == 0 && this.clickedScrollbar) {
114 if (mouseY < (double) this.top) {
115 this.amountScrolled = 0.0D;
116 } else if (mouseY > (double) this.bottom) {
117 this.amountScrolled = this.getMaxScroll();
119 double maxScroll = this.getMaxScroll();
120 if (maxScroll < 1.0D) {
124 double amountScrolled = maxScroll / (double) (this.listHeight - getScrollBarHeight());
125 if (amountScrolled < 1.0D) {
126 amountScrolled = 1.0D;
129 this.amountScrolled += p_mouseDragged_8_ * amountScrolled;
137 private int getMaxScroll() {
138 return Math.max(0, this.contentHeight - (this.listHeight - 4));
141 private int getScrollBarHeight() {
142 return MathHelper.clamp((int) ((float) (this.listHeight * this.listHeight) / (float) this.contentHeight),
144 this.listHeight - PADDING);
148 public boolean mouseScrolled(double mouseX, double mouseY, double scrollAmount) {
149 this.amountScrolled -= scrollAmount * 10;
153 public void render(MatrixStack matrixStack, int mouseX, int mouseY) {
154 this.amountScrolled = MathHelper.clamp(this.amountScrolled, 0.0D, this.getMaxScroll());
156 RenderHelper.disableLighting();
157 // RenderHelper.disableFog();
158 if (!transparentBackground) drawListBackground();
160 int listTop = this.top + PADDING - (int) this.amountScrolled;
162 drawEntries(matrixStack, mouseX, mouseY, listTop);
164 RenderHelper.enableDepthTest();
165 RenderHelper.depthFuncAlways();
167 this.overlayBackground(0, this.top);
168 this.overlayBackground(this.bottom, this.height);
169 RenderHelper.depthFuncLessEqual();
170 RenderHelper.disableDepthTest();
171 RenderHelper.enableBlend();
172 RenderHelper.blendFuncGui();
173 RenderHelper.disableAlphaTest();
174 RenderHelper.shadeModelSmooth();
175 RenderHelper.disableTexture();
176 drawOverlayShadows();
178 int maxScroll = this.getMaxScroll();
180 drawScrollBar(maxScroll);
183 RenderHelper.enableTexture();
184 RenderHelper.shadeModelFlat();
185 RenderHelper.enableAlphaTest();
186 RenderHelper.disableBlend();
189 private void drawListBackground() {
190 RenderHelper.setTexture(DrawableHelper.OPTIONS_BACKGROUND_TEXTURE);
191 Renderer.startTextured()
192 .setColor(32, 32, 32)
194 .addPoint(0, this.bottom, 0.0D, (float) 0 / 32.0F, (float) (this.bottom + (int) this.amountScrolled) / 32.0F)
195 .addPoint(this.width, this.bottom, 0.0D, (float) this.width / 32.0F, (float) (this.bottom + (int) this.amountScrolled) / 32.0F)
196 .addPoint(this.width, this.top, 0.0D, (float) this.width / 32.0F, (float) (this.top + (int) this.amountScrolled) / 32.0F)
197 .addPoint(0, this.top, 0.0D, (float) 0 / 32.0F, (float) (this.top + (int) this.amountScrolled) / 32.0F)
201 private void drawEntries(MatrixStack matrixStack, int mouseX, int mouseY, int top) {
202 for (ControlListEntry entry : this.entries) {
203 if (!entry.isVisible()) continue;
205 entry.setX(this.listLeft);
208 int height = entry.getControlHeight();
209 int bottom = top + height;
210 if(top <= this.bottom && bottom >= this.top) {
211 drawEntry(matrixStack, mouseX, mouseY, top, entry, height);
217 protected void drawEntry(MatrixStack matrixStack, int mouseX, int mouseY, int top, ControlListEntry entry, int height) {
218 entry.render(matrixStack, mouseX, mouseY);
221 private void overlayBackground(int top, int bottom) {
222 RenderHelper.setTexture(DrawableHelper.OPTIONS_BACKGROUND_TEXTURE);
223 Renderer.startTextured()
224 .setColor(64, 64, 64)
226 .addPoint(0, bottom, -100.0D, 0.0D, (float) bottom / 32.0F)
227 .addPoint(this.width, bottom, -100.0D, (float) this.width / 32.0F, (float) bottom / 32.0F)
228 .addPoint(this.width, top, -100.0D, (float) this.width / 32.0F, (float) top / 32.0F)
229 .addPoint(0, top, -100.0D, 0.0D, (float) top / 32.0F)
233 private void drawScrollBar(int maxScroll) {
234 int scrollBarHeight = this.getScrollBarHeight();
235 int scrollBarTop = (int) this.amountScrolled * (this.listHeight - scrollBarHeight) / maxScroll + this.top;
236 if (scrollBarTop < this.top) {
237 scrollBarTop = this.top;
240 Renderer.startTextured()
242 .addPoint(this.scrollBarLeft, this.bottom, 0.0D, 0.0D, 1.0D)
243 .addPoint(this.width, this.bottom, 0.0D, 1.0D, 1.0D)
244 .addPoint(this.width, this.top, 0.0D, 1.0D, 0.0D)
245 .addPoint(this.scrollBarLeft, this.top, 0.0D, 0.0D, 0.0D)
248 Renderer.startTextured()
249 .setColor(128, 128, 128)
251 .addPoint(this.scrollBarLeft, scrollBarTop + scrollBarHeight, 0.0D, 0.0D, 1.0D)
252 .addPoint(this.width, scrollBarTop + scrollBarHeight, 0.0D, 1.0D, 1.0D)
253 .addPoint(this.width, scrollBarTop, 0.0D, 1.0D, 0.0D)
254 .addPoint(this.scrollBarLeft, scrollBarTop, 0.0D, 0.0D, 0.0D)
257 Renderer.startTextured()
258 .setColor(192, 192, 192)
260 .addPoint(this.scrollBarLeft, scrollBarTop + scrollBarHeight - 1, 0.0D, 0.0D, 1.0D)
261 .addPoint(this.width - 1, scrollBarTop + scrollBarHeight - 1, 0.0D, 1.0D, 1.0D)
262 .addPoint(this.width - 1, scrollBarTop, 0.0D, 1.0D, 0.0D)
263 .addPoint(this.scrollBarLeft, scrollBarTop, 0.0D, 0.0D, 0.0D)
267 private void drawOverlayShadows() {
268 Renderer.startTextured()
269 .addPoint(0, this.top + 4, 0.0D, 0.0D, 1.0D)
270 .addPoint(this.width, this.top + 4, 0.0D, 1.0D, 1.0D)
272 .addPoint(this.width, this.top, 0.0D, 1.0D, 0.0D)
273 .addPoint(0, this.top, 0.0D, 0.0D, 0.0D)
275 Renderer.startTextured()
276 .addPoint(this.width, this.bottom - 4, 0.0D, 1.0D, 0.0D)
277 .addPoint(0, this.bottom - 4, 0.0D, 0.0D, 0.0D)
279 .addPoint(0, this.bottom, 0.0D, 0.0D, 1.0D)
280 .addPoint(this.width, this.bottom, 0.0D, 1.0D, 1.0D)
284 ControlList section(String title, CreateControl... createControls) {
285 this.add(new ControlListSection(title, createControls));
289 void setTransparentBackground() {
290 this.transparentBackground = true;
294 public List<? extends IControl> controls() {
299 public IControl getFocused() {
304 public void setFocused(IControl control) {
305 this.focused = control;
309 public boolean isDragging() {
314 public void setDragging(boolean dragging) {
315 this.isDragging = dragging;