]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blob - src/main/java/com/irtimaled/bbor/client/gui/ControlList.java
d15d97135a771929fdd96ba6bae573c2b70e3ffc
[BoundingBoxOutlineReloaded.git] / src / main / java / com / irtimaled / bbor / client / gui / ControlList.java
1 package com.irtimaled.bbor.client.gui;
2
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;
9
10 import java.util.ArrayList;
11 import java.util.List;
12
13 public class ControlList extends AbstractGui implements IControlSet {
14     public static final int CONTROLS_WIDTH = 310;
15     protected static final int PADDING = 8;
16
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;
26
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;
33
34     ControlList(int width, int height, int top, int bottom) {
35         this.minecraft = Minecraft.getInstance();
36         this.width = width;
37         this.scrollBarLeft = width - 6;
38         this.height = height;
39         this.top = top;
40         this.bottom = bottom;
41         this.listHeight = bottom - top;
42         this.listLeft = width / 2 - CONTROLS_WIDTH / 2;
43     }
44
45     void add(ControlListEntry entry) {
46         entry.index = entries.size();
47         addEntry(entry);
48     }
49
50     private void addEntry(ControlListEntry entry) {
51         this.entries.add(entry);
52         this.contentHeight += entry.getControlHeight();
53     }
54
55     public void filter(String lowerValue) {
56         int height = 0;
57
58         for (ControlListEntry entry : entries) {
59             entry.filter(lowerValue);
60             if (entry.isVisible()) {
61                 height += entry.getControlHeight();
62             } else if (entry == focused) {
63                 focused = null;
64             }
65         }
66         this.contentHeight = height + PADDING;
67     }
68
69     void close() {
70         this.entries.forEach(ControlListEntry::close);
71     }
72
73     @Override
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);
79     }
80
81     @Override
82     public boolean isMouseOver(double mouseX, double mouseY) {
83         return mouseY >= (double) this.top && mouseY <= (double) this.bottom;
84     }
85
86     @Override
87     public boolean changeFocus(boolean moveForward) {
88         boolean newControlFocused = IControlSet.super.changeFocus(moveForward);
89         if (newControlFocused) {
90             this.ensureVisible((ControlListEntry) this.getFocused());
91         }
92
93         return newControlFocused;
94     }
95
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);
102             return;
103         }
104
105         int distanceBelowBottom = controlTop + controlHeight - this.bottom;
106         if (distanceBelowBottom > 0) {
107             this.amountScrolled += Math.max(controlHeight, distanceBelowBottom + PADDING);
108         }
109     }
110
111     @Override
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_)) {
114             return true;
115         }
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();
121             } else {
122                 double maxScroll = this.getMaxScroll();
123                 if (maxScroll < 1.0D) {
124                     maxScroll = 1.0D;
125                 }
126
127                 double amountScrolled = maxScroll / (double) (this.listHeight - getScrollBarHeight());
128                 if (amountScrolled < 1.0D) {
129                     amountScrolled = 1.0D;
130                 }
131
132                 this.amountScrolled += p_mouseDragged_8_ * amountScrolled;
133             }
134
135             return true;
136         }
137         return false;
138     }
139
140     private int getMaxScroll() {
141         return Math.max(0, this.contentHeight - (this.listHeight - 4));
142     }
143
144     private int getScrollBarHeight() {
145         return MathHelper.clamp((int) ((float) (this.listHeight * this.listHeight) / (float) this.contentHeight),
146                 32,
147                 this.listHeight - PADDING);
148     }
149
150     @Override
151     public boolean mouseScrolled(double mouseX, double mouseY, double scrollAmount) {
152         this.amountScrolled -= scrollAmount * 10;
153         return true;
154     }
155
156     public void render(int mouseX, int mouseY) {
157         this.amountScrolled = MathHelper.clamp(this.amountScrolled, 0.0D, this.getMaxScroll());
158
159         GL11.glDisable(GL11.GL_LIGHTING);
160         GL11.glDisable(GL11.GL_FOG);
161         if (!transparentBackground) drawListBackground();
162
163         int listTop = this.top + PADDING - (int) this.amountScrolled;
164
165         drawEntries(mouseX, mouseY, listTop);
166
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();
176
177         int maxScroll = this.getMaxScroll();
178         if (maxScroll > 0) {
179             drawScrollBar(maxScroll);
180         }
181
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);
186     }
187
188     private void drawListBackground() {
189         this.minecraft.getTextureManager().bindTexture(AbstractGui.BACKGROUND_LOCATION);
190         Renderer.startTextured()
191                 .setColor(32, 32, 32)
192                 .setAlpha(255)
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)
197                 .render();
198     }
199
200     private void drawEntries(int mouseX, int mouseY, int top) {
201         for (ControlListEntry entry : this.entries) {
202             if (!entry.isVisible()) continue;
203
204             entry.setX(this.listLeft);
205             entry.setY(top);
206
207             int height = entry.getControlHeight();
208             drawEntry(mouseX, mouseY, top, entry, height);
209             top += height;
210         }
211     }
212
213     protected void drawEntry(int mouseX, int mouseY, int top, ControlListEntry entry, int height) {
214         entry.render(mouseX, mouseY);
215     }
216
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)
222                 .setAlpha(255)
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)
227                 .render();
228     }
229
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;
235         }
236
237         Renderer.startTextured()
238                 .setAlpha(255)
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)
243                 .render();
244
245         Renderer.startTextured()
246                 .setColor(128, 128, 128)
247                 .setAlpha(255)
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)
252                 .render();
253
254         Renderer.startTextured()
255                 .setColor(192, 192, 192)
256                 .setAlpha(255)
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)
261                 .render();
262     }
263
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)
268                 .setAlpha(255)
269                 .addPoint(this.width, this.top, 0.0D, 1.0D, 0.0D)
270                 .addPoint(0, this.top, 0.0D, 0.0D, 0.0D)
271                 .render();
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)
275                 .setAlpha(255)
276                 .addPoint(0, this.bottom, 0.0D, 0.0D, 1.0D)
277                 .addPoint(this.width, this.bottom, 0.0D, 1.0D, 1.0D)
278                 .render();
279     }
280
281     ControlList section(String title, CreateControl... createControls) {
282         this.add(new ControlListSection(title, createControls));
283         return this;
284     }
285
286     void setTransparentBackground() {
287         this.transparentBackground = true;
288     }
289
290     @Override
291     public List<? extends IControl> controls() {
292         return entries;
293     }
294
295     @Override
296     public IControl getFocused() {
297         return focused;
298     }
299
300     @Override
301     public void setFocused(IControl control) {
302         this.focused = control;
303     }
304
305     @Override
306     public boolean isDragging() {
307         return isDragging;
308     }
309
310     @Override
311     public void setDragging(boolean dragging) {
312         this.isDragging = dragging;
313     }
314 }