]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/commitdiff
Change gui to use scrollable control list
authorIrtimaled <irtimaled@gmail.com>
Wed, 8 Apr 2020 09:25:45 +0000 (02:25 -0700)
committerIrtimaled <irtimaled@gmail.com>
Mon, 18 May 2020 00:28:01 +0000 (17:28 -0700)
22 files changed:
src/main/java/com/irtimaled/bbor/client/gui/AbstractButton.java
src/main/java/com/irtimaled/bbor/client/gui/AbstractControl.java [new file with mode: 0644]
src/main/java/com/irtimaled/bbor/client/gui/AbstractSlider.java
src/main/java/com/irtimaled/bbor/client/gui/BoolButton.java [new file with mode: 0644]
src/main/java/com/irtimaled/bbor/client/gui/BoolSettingButton.java
src/main/java/com/irtimaled/bbor/client/gui/BoundingBoxTypeButton.java
src/main/java/com/irtimaled/bbor/client/gui/ControlList.java [new file with mode: 0644]
src/main/java/com/irtimaled/bbor/client/gui/ControlListEntry.java [new file with mode: 0644]
src/main/java/com/irtimaled/bbor/client/gui/ControlListSection.java [new file with mode: 0644]
src/main/java/com/irtimaled/bbor/client/gui/CreateControl.java
src/main/java/com/irtimaled/bbor/client/gui/IControl.java
src/main/java/com/irtimaled/bbor/client/gui/IRenderableControl.java [deleted file]
src/main/java/com/irtimaled/bbor/client/gui/IRowHeight.java [deleted file]
src/main/java/com/irtimaled/bbor/client/gui/IntSettingSlider.java
src/main/java/com/irtimaled/bbor/client/gui/ListScreen.java [new file with mode: 0644]
src/main/java/com/irtimaled/bbor/client/gui/MaxYSettingSlider.java
src/main/java/com/irtimaled/bbor/client/gui/SearchField.java [new file with mode: 0644]
src/main/java/com/irtimaled/bbor/client/gui/SettingsScreen.java
src/main/java/com/irtimaled/bbor/client/gui/SettingsScreenButton.java
src/main/java/com/irtimaled/bbor/client/renderers/Renderer.java
src/main/java/com/irtimaled/bbor/mixin/client/gui/MixinGuiOptions.java
src/main/resources/assets/bbor/lang/en_us.json

index 234199171bedc1b92b84b02e411821ae01b3c807..4951981c60a6d40edc78874773fb6f0b8e4f9938 100644 (file)
@@ -1,31 +1,15 @@
 package com.irtimaled.bbor.client.gui;
 
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.GuiButton;
-
-abstract class AbstractButton extends GuiButton implements IRenderableControl {
-    AbstractButton(int id, int x, int y, int width, String name) {
-        super(id, x, y, width, 20, name);
+abstract class AbstractButton extends AbstractControl {
+    AbstractButton(int x, int y, int width, String name) {
+        super(x, y, width, name);
     }
 
-    AbstractButton(int id, int x, int y, int width, String name, boolean enabled) {
-        this(id, x, y, width, name);
+    AbstractButton(int x, int y, int width, String name, boolean enabled) {
+        this(x, y, width, name);
         this.enabled = enabled;
     }
 
-    @Override
-    public void render(int mouseX, int mouseY) {
-        super.render(mouseX, mouseY, 0f);
-    }
-
-    @Override
-    protected void renderBg(Minecraft p_renderBg_1_, int p_renderBg_2_, int p_renderBg_3_) {
-        renderBackground();
-    }
-
-    protected void renderBackground() {
-    }
-
     @Override
     protected int getHoverState(boolean p_getHoverState_1_) {
         return getState();
@@ -43,3 +27,4 @@ abstract class AbstractButton extends GuiButton implements IRenderableControl {
 
     protected abstract void onPressed();
 }
+
diff --git a/src/main/java/com/irtimaled/bbor/client/gui/AbstractControl.java b/src/main/java/com/irtimaled/bbor/client/gui/AbstractControl.java
new file mode 100644 (file)
index 0000000..4dab978
--- /dev/null
@@ -0,0 +1,71 @@
+package com.irtimaled.bbor.client.gui;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.GuiButton;
+
+import java.awt.*;
+
+abstract class AbstractControl extends GuiButton implements IControl {
+    private static final int PADDING = 4;
+    protected final Minecraft minecraft;
+
+    AbstractControl(int x, int y, int width, String name) {
+        super(0, x, y, width, 20, name);
+        this.minecraft = Minecraft.getInstance();
+    }
+
+    @Override
+    public void render(int mouseX, int mouseY) {
+        super.render(mouseX, mouseY, 0f);
+    }
+
+    @Override
+    public void setX(int x) {
+        super.x = x;
+    }
+
+    @Override
+    public void setY(int y) {
+        super.y = y;
+    }
+
+    @Override
+    public int getControlHeight() {
+        return this.height + PADDING;
+    }
+
+    @Override
+    public int getControlWidth() {
+        return this.width + PADDING;
+    }
+
+    @Override
+    protected void renderBg(Minecraft minecraft, int mouseX, int mouseY) {
+        if (enabled) renderBackground(mouseX, mouseY);
+    }
+
+    protected void renderBackground(int mouseX, int mouseY) {
+    }
+
+    @Override
+    public void setVisible(boolean visible) {
+        this.visible = visible;
+    }
+
+    @Override
+    public boolean getVisible() {
+        return this.visible;
+    }
+
+    @Override
+    public void filter(String lowerValue) {
+        String lowerString = this.displayString.toLowerCase();
+        this.setVisible(lowerValue.equals("") ||
+                lowerString.startsWith(lowerValue) ||
+                lowerString.contains(" " + lowerValue));
+    }
+
+    void drawRectangle(int left, int top, int right, int bottom, Color color) {
+        drawRect(left, top, right, bottom, color.getRGB());
+    }
+}
index 059ce943e642c636bad7d35804bca769f320ceaa..0cd402460d4aa410d31a16a9d2ddf943b18be581 100644 (file)
@@ -1,28 +1,27 @@
 package com.irtimaled.bbor.client.gui;
 
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.GuiButton;
 import net.minecraft.util.math.MathHelper;
 import org.lwjgl.opengl.GL11;
 
-abstract class AbstractSlider extends GuiButton implements IRenderableControl {
+abstract class AbstractSlider extends AbstractControl {
     double progress;
+    private boolean isDragging;
 
-    AbstractSlider(int id, int x, int y, int width) {
-        super(id, x, y, width, 20, "");
+    AbstractSlider(int x, int y, int width) {
+        super(x, y, width, "");
     }
 
     @Override
-    public void render(int mouseX, int mouseY) {
-        super.render(mouseX, mouseY, 0f);
-    }
-
-    @Override
-    protected void renderBg(Minecraft minecraft, int mouseX, int mouseY) {
-        minecraft.getTextureManager().bindTexture(BUTTON_TEXTURES);
+    protected void renderBackground(int mouseX, int mouseY) {
+        this.minecraft.getTextureManager().bindTexture(BUTTON_TEXTURES);
         GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
-        this.drawTexturedModalRect(this.x + (int) (this.progress * (double) (this.width - 8)), this.y, 0, 66, 4, 20);
-        this.drawTexturedModalRect(this.x + (int) (this.progress * (double) (this.width - 8)) + 4, this.y, 196, 66, 4, 20);
+        if(isDragging) {
+            changeProgress(mouseX);
+        }
+
+        int hoverState = super.getHoverState(this.hovered);
+        this.drawTexturedModalRect(this.x + (int) (this.progress * (double) (this.width - 8)), this.y, 0, 46 + hoverState * 20, 4, this.height);
+        this.drawTexturedModalRect(this.x + (int) (this.progress * (double) (this.width - 8)) + 4, this.y, 196, 46 + hoverState * 20, 4, 20);
     }
 
     boolean setProgress(double progress) {
@@ -49,13 +48,17 @@ abstract class AbstractSlider extends GuiButton implements IRenderableControl {
     @Override
     protected void onDrag(double mouseX, double mouseY, double deltaX, double deltaY) {
         changeProgress(mouseX);
-        super.onDrag(mouseX, mouseY, deltaX, deltaY);
     }
 
     @Override
     public void onClick(double mouseX, double mouseY) {
         changeProgress(mouseX);
-        super.onClick(mouseX, mouseY);
+        isDragging = true;
+    }
+
+    @Override
+    public void onRelease(double mouseX, double mouseY) {
+        this.isDragging = false;
     }
 
     protected abstract void updateText();
diff --git a/src/main/java/com/irtimaled/bbor/client/gui/BoolButton.java b/src/main/java/com/irtimaled/bbor/client/gui/BoolButton.java
new file mode 100644 (file)
index 0000000..3b42bbe
--- /dev/null
@@ -0,0 +1,26 @@
+package com.irtimaled.bbor.client.gui;
+
+public abstract class BoolButton extends AbstractButton {
+    private boolean value;
+
+    BoolButton(int width, String label, boolean enabled) {
+        super(0, 0, width, label, enabled);
+    }
+
+    BoolButton(int width, String label) {
+        super(0, 0, width, label);
+    }
+
+    @Override
+    protected int getState() {
+        return enabled ? this.getValue() ? 2 : 1 : 0;
+    }
+
+    protected boolean getValue() {
+        return this.value;
+    }
+
+    protected void setValue(boolean value) {
+        this.value = value;
+    }
+}
index f6ca98c06ef0c11128745021c5e873d86f01c33f..da3c1158cd8f8bba487e465a4760336f84baca8d 100644 (file)
@@ -3,21 +3,21 @@ package com.irtimaled.bbor.client.gui;
 import com.irtimaled.bbor.config.ConfigManager;
 import com.irtimaled.bbor.config.Setting;
 
-public class BoolSettingButton extends AbstractButton {
+public class BoolSettingButton extends BoolButton {
     private final Setting<Boolean> setting;
 
-    BoolSettingButton(int id, int x, int y, int width, String label, Setting<Boolean> setting) {
-        super(id, x, y, width, label);
+    BoolSettingButton(int width, String label, Setting<Boolean> setting) {
+        super(width, label);
         this.setting = setting;
     }
 
     @Override
-    protected int getState() {
-        return enabled ? setting.get() ? 2 : 1 : 0;
+    public void onPressed() {
+        ConfigManager.Toggle(this.setting);
     }
 
     @Override
-    public void onPressed() {
-        ConfigManager.Toggle(setting);
+    protected boolean getValue() {
+        return this.setting.get();
     }
 }
index d44f0586852793442903bf077e70ac5f8dddb07e..5c85899fe01cc0a6eaba3755f28b21d7f035d293 100644 (file)
@@ -7,20 +7,13 @@ import java.awt.*;
 public class BoundingBoxTypeButton extends BoolSettingButton {
     private final Color color;
 
-    BoundingBoxTypeButton(int id, int x, int y, int width, String label, BoundingBoxType type) {
-        super(id, x, y, width, label, type.shouldRenderSetting);
+    BoundingBoxTypeButton(int width, String label, BoundingBoxType type) {
+        super(width, label, type.shouldRenderSetting);
         color = type.getColor();
     }
 
-    public BoundingBoxTypeButton(int id, int x, int y, int width, String label, BoundingBoxType type, boolean enabled) {
-        this(id, x, y, width, label, type);
-        this.enabled = enabled;
-    }
-
     @Override
-    protected void renderBackground() {
-        if (!enabled) return;
-
+    protected void renderBackground(int mouseX, int mouseY) {
         int left = x + 1;
         int top = y + 1;
         int right = left + width - 2;
@@ -40,8 +33,4 @@ public class BoundingBoxTypeButton extends BoolSettingButton {
         drawRectangle(left + 1, bottom - 2, right, bottom, darkest);
         drawRectangle(right - 1, top + 1, right, bottom, darkest);
     }
-
-    private void drawRectangle(int left, int top, int right, int bottom, Color color) {
-        drawRect(left, top, right, bottom, color.getRGB());
-    }
 }
diff --git a/src/main/java/com/irtimaled/bbor/client/gui/ControlList.java b/src/main/java/com/irtimaled/bbor/client/gui/ControlList.java
new file mode 100644 (file)
index 0000000..954d65d
--- /dev/null
@@ -0,0 +1,322 @@
+package com.irtimaled.bbor.client.gui;
+
+import com.irtimaled.bbor.client.renderers.Renderer;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.gui.GuiEventHandler;
+import net.minecraft.client.gui.IGuiEventListener;
+import net.minecraft.client.renderer.OpenGlHelper;
+import net.minecraft.util.math.MathHelper;
+import org.lwjgl.opengl.GL11;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class ControlList extends GuiEventHandler {
+    private static final int CONTROLS_WIDTH = 310;
+    private final int scrollBarLeft;
+    private final int listHeight;
+    private final int listLeft;
+    private final int listRight;
+    private final Minecraft minecraft;
+    private final List<ControlListEntry> entries = new ArrayList<>();
+    private final int width;
+    private final int height;
+    private final int top;
+    private final int bottom;
+
+    private int contentHeight = 8;
+    private int selectedElement;
+    private double amountScrolled;
+    private boolean clickedScrollbar;
+    private boolean showSelectionBox;
+    private boolean transparentBackground;
+
+    ControlList(int width, int height, int top, int bottom) {
+        this.minecraft = Minecraft.getInstance();
+        this.width = width;
+        this.scrollBarLeft = width - 6;
+        this.height = height;
+        this.top = top;
+        this.bottom = bottom;
+        this.listHeight = bottom - top;
+        this.listLeft = width / 2 - CONTROLS_WIDTH / 2;
+        this.listRight = this.listLeft + CONTROLS_WIDTH;
+        this.selectedElement = -1;
+    }
+
+    void add(ControlListEntry entry) {
+        entry.list = this;
+        entry.index = entries.size();
+        addEntry(entry);
+    }
+
+    private void addEntry(ControlListEntry entry) {
+        this.entries.add(entry);
+        this.contentHeight += entry.getControlHeight();
+    }
+
+    ControlListEntry getSelectedEntry() {
+        return this.selectedElement >= 0 && this.selectedElement < this.entries.size() ? this.entries.get(this.selectedElement) : null;
+    }
+
+    void filter(String lowerValue) {
+        int height = 0;
+        for (IControl entry : entries) {
+            entry.filter(lowerValue);
+            if (entry.getVisible())
+                height += entry.getControlHeight();
+        }
+        this.contentHeight = height + 8;
+    }
+
+    void close() {
+        this.entries.forEach(ControlListEntry::close);
+    }
+
+    @Override
+    public boolean mouseClicked(double mouseX, double mouseY, int button) {
+        this.clickedScrollbar = button == 0 && mouseX >= (double) this.scrollBarLeft;
+        if (mouseY >= (double) this.top && mouseY <= (double) this.bottom) {
+            ControlListEntry entry = this.getEntryAt(mouseX, mouseY);
+            if (entry != null && entry.mouseClicked(mouseX, mouseY, button)) {
+                this.setDragging(true);
+                this.setSelectedIndex(entry.index);
+                return true;
+            } else {
+                return this.clickedScrollbar;
+            }
+        } else {
+            return false;
+        }
+    }
+
+    void setSelectedIndex(int index) {
+        this.selectedElement = index;
+    }
+
+    private ControlListEntry getEntryAt(double mouseX, double mouseY) {
+        if (mouseX >= listLeft && mouseX <= listRight) {
+            for (ControlListEntry entry : entries) {
+                if (!entry.getVisible()) continue;
+
+                int top = entry.getY();
+                int bottom = top + entry.getControlHeight();
+                if (mouseY >= top && mouseY <= bottom)
+                    return entry;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public boolean mouseDragged(double mouseX, double mouseY, int button, double p_mouseDragged_6_, double p_mouseDragged_8_) {
+        if (super.mouseDragged(mouseX, mouseY, button, p_mouseDragged_6_, p_mouseDragged_8_)) {
+            return true;
+        } else if (button == 0 && this.clickedScrollbar) {
+            if (mouseY < (double) this.top) {
+                this.amountScrolled = 0.0D;
+            } else if (mouseY > (double) this.bottom) {
+                this.amountScrolled = this.getMaxScroll();
+            } else {
+                double maxScroll = this.getMaxScroll();
+                if (maxScroll < 1.0D) {
+                    maxScroll = 1.0D;
+                }
+
+                double amountScrolled = maxScroll / (double) (this.listHeight - getScrollBarHeight());
+                if (amountScrolled < 1.0D) {
+                    amountScrolled = 1.0D;
+                }
+
+                this.amountScrolled += p_mouseDragged_8_ * amountScrolled;
+            }
+
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private int getMaxScroll() {
+        return Math.max(0, this.contentHeight - (this.listHeight - 4));
+    }
+
+    private int getScrollBarHeight() {
+        return MathHelper.clamp((int) ((float) (this.listHeight * this.listHeight) / (float) this.contentHeight),
+                32,
+                this.listHeight - 8);
+    }
+
+    @Override
+    public boolean mouseReleased(double mouseX, double mouseY, int button) {
+        this.entries.forEach(entry -> entry.mouseReleased(mouseX, mouseY, button));
+        return false;
+    }
+
+    @Override
+    public boolean mouseScrolled(double scrollAmount) {
+        this.amountScrolled -= scrollAmount * 10;
+        return true;
+    }
+
+    public void render(int mouseX, int mouseY) {
+        this.amountScrolled = MathHelper.clamp(this.amountScrolled, 0.0D, this.getMaxScroll());
+
+        GL11.glDisable(GL11.GL_LIGHTING);
+        GL11.glDisable(GL11.GL_FOG);
+        if (!transparentBackground) drawListBackground();
+
+        int listTop = this.top + 8 - (int) this.amountScrolled;
+
+        drawEntries(mouseX, mouseY, listTop);
+
+        GL11.glDisable(GL11.GL_DEPTH_TEST);
+        this.overlayBackground(0, this.top);
+        this.overlayBackground(this.bottom, this.height);
+        GL11.glEnable(GL11.GL_BLEND);
+        OpenGlHelper.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ZERO, GL11.GL_ONE);
+        GL11.glDisable(GL11.GL_ALPHA_TEST);
+        GL11.glShadeModel(GL11.GL_SMOOTH);
+        GL11.glDisable(GL11.GL_TEXTURE_2D);
+        drawOverlayShadows();
+
+        int maxScroll = this.getMaxScroll();
+        if (maxScroll > 0) {
+            drawScrollBar(maxScroll);
+        }
+
+        GL11.glEnable(GL11.GL_TEXTURE_2D);
+        GL11.glShadeModel(GL11.GL_FLAT);
+        GL11.glEnable(GL11.GL_ALPHA_TEST);
+        GL11.glDisable(GL11.GL_BLEND);
+    }
+
+    private void drawListBackground() {
+        this.minecraft.getTextureManager().bindTexture(Gui.OPTIONS_BACKGROUND);
+        Renderer.startTextured()
+                .setColor(32, 32, 32)
+                .setAlpha(255)
+                .addPoint(0, this.bottom, 0.0D, (float) 0 / 32.0F, (float) (this.bottom + (int) this.amountScrolled) / 32.0F)
+                .addPoint(this.width, this.bottom, 0.0D, (float) this.width / 32.0F, (float) (this.bottom + (int) this.amountScrolled) / 32.0F)
+                .addPoint(this.width, this.top, 0.0D, (float) this.width / 32.0F, (float) (this.top + (int) this.amountScrolled) / 32.0F)
+                .addPoint(0, this.top, 0.0D, (float) 0 / 32.0F, (float) (this.top + (int) this.amountScrolled) / 32.0F)
+                .render();
+    }
+
+    private void drawEntries(int mouseX, int mouseY, int top) {
+        for (ControlListEntry entry : this.entries) {
+            if (!entry.getVisible()) continue;
+
+            entry.setX(this.listLeft);
+            entry.setY(top);
+
+            int height = entry.getControlHeight();
+
+            if (this.showSelectionBox && this.selectedElement == entry.index) {
+                GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
+                GL11.glDisable(GL11.GL_TEXTURE_2D);
+                Renderer.startTextured()
+                        .setAlpha(255)
+                        .setColor(128, 128, 128)
+                        .addPoint((double) this.listLeft - 2, (double) (top + height) - 2, 0.0D, 0.0D, 1.0D)
+                        .addPoint((double) this.listRight + 2, (double) (top + height) - 2, 0.0D, 1.0D, 1.0D)
+                        .addPoint((double) this.listRight + 2, top - 2, 0.0D, 1.0D, 0.0D)
+                        .addPoint((double) this.listLeft - 2, top - 2, 0.0D, 0.0D, 0.0D)
+                        .setColor(0, 0, 0)
+                        .addPoint(this.listLeft - 1, (double) (top + height) - 3, 0.0D, 0.0D, 1.0D)
+                        .addPoint(this.listRight + 1, (double) (top + height) - 3, 0.0D, 1.0D, 1.0D)
+                        .addPoint(this.listRight + 1, top - 1, 0.0D, 1.0D, 0.0D)
+                        .addPoint(this.listLeft - 1, top - 1, 0.0D, 0.0D, 0.0D)
+                        .render();
+                GL11.glEnable(GL11.GL_TEXTURE_2D);
+            }
+
+            entry.render(mouseX, mouseY);
+            top += entry.getControlHeight();
+        }
+    }
+
+    private void overlayBackground(int top, int bottom) {
+        this.minecraft.getTextureManager().bindTexture(Gui.OPTIONS_BACKGROUND);
+        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
+        Renderer.startTextured()
+                .setColor(64, 64, 64)
+                .setAlpha(255)
+                .addPoint(0, bottom, 0.0D, 0.0D, (float) bottom / 32.0F)
+                .addPoint(this.width, bottom, 0.0D, (float) this.width / 32.0F, (float) bottom / 32.0F)
+                .addPoint(this.width, top, 0.0D, (float) this.width / 32.0F, (float) top / 32.0F)
+                .addPoint(0, top, 0.0D, 0.0D, (float) top / 32.0F)
+                .render();
+    }
+
+    private void drawScrollBar(int maxScroll) {
+        int scrollBarHeight = this.getScrollBarHeight();
+        int scrollBarTop = (int) this.amountScrolled * (this.listHeight - scrollBarHeight) / maxScroll + this.top;
+        if (scrollBarTop < this.top) {
+            scrollBarTop = this.top;
+        }
+
+        Renderer.startTextured()
+                .setAlpha(255)
+                .addPoint(this.scrollBarLeft, this.bottom, 0.0D, 0.0D, 1.0D)
+                .addPoint(this.width, this.bottom, 0.0D, 1.0D, 1.0D)
+                .addPoint(this.width, this.top, 0.0D, 1.0D, 0.0D)
+                .addPoint(this.scrollBarLeft, this.top, 0.0D, 0.0D, 0.0D)
+                .render();
+
+        Renderer.startTextured()
+                .setColor(128, 128, 128)
+                .setAlpha(255)
+                .addPoint(this.scrollBarLeft, scrollBarTop + scrollBarHeight, 0.0D, 0.0D, 1.0D)
+                .addPoint(this.width, scrollBarTop + scrollBarHeight, 0.0D, 1.0D, 1.0D)
+                .addPoint(this.width, scrollBarTop, 0.0D, 1.0D, 0.0D)
+                .addPoint(this.scrollBarLeft, scrollBarTop, 0.0D, 0.0D, 0.0D)
+                .render();
+
+        Renderer.startTextured()
+                .setColor(192, 192, 192)
+                .setAlpha(255)
+                .addPoint(this.scrollBarLeft, scrollBarTop + scrollBarHeight - 1, 0.0D, 0.0D, 1.0D)
+                .addPoint(this.width - 1, scrollBarTop + scrollBarHeight - 1, 0.0D, 1.0D, 1.0D)
+                .addPoint(this.width - 1, scrollBarTop, 0.0D, 1.0D, 0.0D)
+                .addPoint(this.scrollBarLeft, scrollBarTop, 0.0D, 0.0D, 0.0D)
+                .render();
+    }
+
+    private void drawOverlayShadows() {
+        Renderer.startTextured()
+                .addPoint(0, this.top + 4, 0.0D, 0.0D, 1.0D)
+                .addPoint(this.width, this.top + 4, 0.0D, 1.0D, 1.0D)
+                .setAlpha(255)
+                .addPoint(this.width, this.top, 0.0D, 1.0D, 0.0D)
+                .addPoint(0, this.top, 0.0D, 0.0D, 0.0D)
+                .render();
+        Renderer.startTextured()
+                .addPoint(this.width, this.bottom - 4, 0.0D, 1.0D, 0.0D)
+                .addPoint(0, this.bottom - 4, 0.0D, 0.0D, 0.0D)
+                .setAlpha(255)
+                .addPoint(0, this.bottom, 0.0D, 0.0D, 1.0D)
+                .addPoint(this.width, this.bottom, 0.0D, 1.0D, 1.0D)
+                .render();
+    }
+
+    @Override
+    protected List<? extends IGuiEventListener> getChildren() {
+        return Collections.emptyList();
+    }
+
+    ControlList section(String title, CreateControl... createControls) {
+        this.add(new ControlListSection(title, createControls));
+        return this;
+    }
+
+    void showSelectionBox() {
+        this.showSelectionBox = true;
+    }
+
+    void setTransparentBackground() {
+        this.transparentBackground = true;
+    }
+}
diff --git a/src/main/java/com/irtimaled/bbor/client/gui/ControlListEntry.java b/src/main/java/com/irtimaled/bbor/client/gui/ControlListEntry.java
new file mode 100644 (file)
index 0000000..1521bfe
--- /dev/null
@@ -0,0 +1,42 @@
+package com.irtimaled.bbor.client.gui;
+
+public abstract class ControlListEntry implements IControl {
+    int index;
+    ControlList list;
+    private int x;
+    private int y;
+    private boolean visible = true;
+
+    public void close() { }
+
+    @Override
+    public int getControlHeight() { return 24; }
+
+    public int getX() {
+        return x;
+    }
+
+    public int getY() {
+        return y;
+    }
+
+    @Override
+    public void setX(int x) {
+        this.x = x;
+    }
+
+    @Override
+    public void setY(int y) {
+        this.y = y;
+    }
+
+    @Override
+    public void setVisible(boolean visible) {
+        this.visible = visible;
+    }
+
+    @Override
+    public boolean getVisible() {
+        return visible;
+    }
+}
diff --git a/src/main/java/com/irtimaled/bbor/client/gui/ControlListSection.java b/src/main/java/com/irtimaled/bbor/client/gui/ControlListSection.java
new file mode 100644 (file)
index 0000000..cdd1552
--- /dev/null
@@ -0,0 +1,133 @@
+package com.irtimaled.bbor.client.gui;
+
+import net.minecraft.client.Minecraft;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ControlListSection extends ControlListEntry {
+    private static final int TITLE_HEIGHT = 16;
+    private static final int CONTROLS_WIDTH = 310;
+    private final String title;
+    private final List<IControl> controls = new ArrayList<>();
+    private final Minecraft minecraft = Minecraft.getInstance();
+    private final int titleHeight;
+    private int height;
+
+    ControlListSection(String title, CreateControl... createControls) {
+        this.title = title;
+        this.titleHeight = title != null ? TITLE_HEIGHT : 0;
+        this.height = titleHeight;
+
+        int columnCount = columnCount();
+        int controlWidth = (CONTROLS_WIDTH - ((columnCount - 1) * 4)) / columnCount;
+
+        int column = 0;
+        for (CreateControl createControl : createControls) {
+            IControl control = createControl.create(0, controlWidth);
+            if(control == null) continue;
+
+            this.controls.add(control);
+            if (column == 0) {
+                this.height += control.getControlHeight();
+            }
+            column = (column + 1) % columnCount;
+        }
+    }
+
+    private int columnCount() {
+        switch (minecraft.getLanguageManager().getCurrentLanguage().getLanguageCode()){
+            case "en_au":
+            case "en_us":
+            case "en_gb": return 3;
+        }
+        return 2;
+    }
+
+    @Override
+    public void render(int mouseX, int mouseY) {
+        int x = this.getX();
+        int y = this.getY();
+        int top = y;
+        if(this.title != null) {
+            this.minecraft.fontRenderer.drawString(this.title, x + 4, y + ((TITLE_HEIGHT - this.minecraft.fontRenderer.FONT_HEIGHT) / 1.5f), 16777215);
+            top += titleHeight;
+        }
+
+        int left = 0;
+        int height = 0;
+        for(IControl control : controls) {
+            if(!control.getVisible()) continue;
+
+            control.setX(left + x);
+            control.setY(top);
+            control.render(mouseX, mouseY);
+            if(left == 0) {
+                height = control.getControlHeight();
+            }
+            left += control.getControlWidth();
+            if(left >= CONTROLS_WIDTH) {
+                left = 0;
+                top += height;
+            }
+        }
+    }
+
+    @Override
+    public int getControlHeight() {
+        return this.height;
+    }
+
+    @Override
+    public int getControlWidth() {
+        return CONTROLS_WIDTH;
+    }
+
+    @Override
+    public boolean mouseClicked(double mouseX, double mouseY, int button) {
+        for (IControl control : controls) {
+            if (control.getVisible() && control.mouseClicked(mouseX, mouseY, button)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean mouseReleased(double mouseX, double mouseY, int button) {
+        boolean result = false;
+        for (IControl control : controls) {
+            if (control.mouseReleased(mouseX, mouseY, button)) result = true;
+        }
+        return result;
+    }
+
+    @Override
+    public void filter(String lowerValue) {
+        if(matchesTitle(lowerValue)) lowerValue = "";
+
+        int height = 0;
+        int left = 0;
+        for (IControl entry : controls) {
+            entry.filter(lowerValue);
+            if (entry.getVisible()) {
+                if (left == 0)
+                    height += entry.getControlHeight();
+                left += entry.getControlWidth();
+                if (left >= getControlWidth()) {
+                    left = 0;
+                }
+            }
+        }
+        this.height = height + titleHeight;
+        this.setVisible(height > 0);
+    }
+
+    private boolean matchesTitle(String lowerValue) {
+        if (this.title == null) return false;
+
+        String lowerString = this.title.toLowerCase();
+        return lowerString.startsWith(lowerValue) ||
+                lowerString.contains(" " + lowerValue);
+    }
+}
index 8dd7827a4d2ec110413eee97d43a57376aa56b34..7ea950fb530865316da41ef02a42da11a5076e66 100644 (file)
@@ -2,5 +2,5 @@ package com.irtimaled.bbor.client.gui;
 
 @FunctionalInterface
 interface CreateControl {
-    IControl create(Integer id, Integer x, Integer y, Integer width);
+    IControl create(Integer x, Integer width);
 }
index 83252f36cc241dbafabde576c95b1a2792da9abf..17db2ba985d11affd4ae0dbd58ce796e9382baf6 100644 (file)
@@ -1,4 +1,24 @@
 package com.irtimaled.bbor.client.gui;
 
-interface IControl {
+import net.minecraft.client.gui.IGuiEventListener;
+
+interface IControl extends IGuiEventListener {
+    void render(int mouseX, int mouseY);
+
+    void setX(int x);
+
+    void setY(int y);
+
+    int getControlWidth();
+
+    int getControlHeight();
+
+    boolean getVisible();
+
+    void setVisible(boolean visible);
+
+    void filter(String lowerValue);
+
+    default void close() {
+    }
 }
diff --git a/src/main/java/com/irtimaled/bbor/client/gui/IRenderableControl.java b/src/main/java/com/irtimaled/bbor/client/gui/IRenderableControl.java
deleted file mode 100644 (file)
index 62bcb60..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.irtimaled.bbor.client.gui;
-
-interface IRenderableControl extends IControl {
-    void render(int mouseX, int mouseY);
-}
diff --git a/src/main/java/com/irtimaled/bbor/client/gui/IRowHeight.java b/src/main/java/com/irtimaled/bbor/client/gui/IRowHeight.java
deleted file mode 100644 (file)
index 7536212..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.irtimaled.bbor.client.gui;
-
-interface IRowHeight extends IControl {
-    double getRowHeight();
-}
index 14f0ba9d6172b1ad961829467788bcc3f3d1d22b..2c7eb62975514274447ee500d6be01cfbdac6e3f 100644 (file)
@@ -6,7 +6,7 @@ import net.minecraft.client.resources.I18n;
 import java.util.HashMap;
 import java.util.Map;
 
-class IntSettingSlider extends AbstractSlider implements IRenderableControl {
+class IntSettingSlider extends AbstractSlider {
     private final String format;
     private final Map<Integer, String> displayValues = new HashMap<>();
 
@@ -14,8 +14,8 @@ class IntSettingSlider extends AbstractSlider implements IRenderableControl {
     final int minValue;
     final int range;
 
-    IntSettingSlider(int id, int x, int y, int width, int minValue, int maxValue, String format, Setting<Integer> setting) {
-        super(id, x, y, width);
+    IntSettingSlider(int width, int minValue, int maxValue, String format, Setting<Integer> setting) {
+        super(0, 0, width);
         this.setting = setting;
         this.minValue = minValue;
         this.format = format;
diff --git a/src/main/java/com/irtimaled/bbor/client/gui/ListScreen.java b/src/main/java/com/irtimaled/bbor/client/gui/ListScreen.java
new file mode 100644 (file)
index 0000000..9e8da44
--- /dev/null
@@ -0,0 +1,91 @@
+package com.irtimaled.bbor.client.gui;
+
+import net.minecraft.client.gui.GuiScreen;
+import net.minecraft.client.resources.I18n;
+
+public abstract class ListScreen extends GuiScreen {
+    private final GuiScreen lastScreen;
+
+    private AbstractButton doneButton;
+    private String title;
+    private ControlList controlList;
+    private SearchField searchField;
+
+    ListScreen(GuiScreen lastScreen) {
+        this.lastScreen = lastScreen;
+    }
+
+    ListScreen() {
+        this(null);
+    }
+
+    protected void onDoneClicked() {
+        mc.displayGuiScreen(lastScreen);
+    }
+
+    @Override
+    protected void initGui() {
+        this.title = "Bounding Box Outline Reloaded";
+        this.controlList = new ControlList(this.width, this.height, 48, this.height - 28);
+        this.searchField = new SearchField(this.fontRenderer, this.width / 2 - 100, 22, 200, 20, this.controlList);
+        this.doneButton = new AbstractButton(this.width / 2 - 100, this.height - 24, 200, I18n.format("gui.done")) {
+            @Override
+            public void onPressed() {
+                onDoneClicked();
+            }
+        };
+
+        this.children.add(this.doneButton);
+        this.children.add(this.controlList);
+        this.children.add(this.searchField);
+        this.setup();
+    }
+
+    protected abstract void setup();
+
+    @Override
+    public void render(int mouseX, int mouseY, float unknown) {
+        render(mouseX, mouseY);
+    }
+
+    protected void render(int mouseX, int mouseY) {
+        this.controlList.render(mouseX, mouseY);
+
+        this.drawCenteredString(this.fontRenderer, this.title, this.width / 2, 8, 16777215);
+        this.searchField.render(mouseX, mouseY);
+        this.doneButton.render(mouseX, mouseY);
+    }
+
+    @Override
+    public void tick() {
+        this.searchField.tick();
+    }
+
+    @Override
+    public boolean keyPressed(int key, int scanCode, int modifiers) {
+        return super.keyPressed(key, scanCode, modifiers) || this.searchField.keyPressed(key, scanCode, modifiers);
+    }
+
+    @Override
+    public boolean charTyped(char character, int modifiers) {
+        return this.searchField.charTyped(character, modifiers);
+    }
+
+    @Override
+    public boolean mouseScrolled(double scrollAmount) {
+        return this.controlList.mouseScrolled(scrollAmount);
+    }
+
+    @Override
+    public void onGuiClosed() {
+        this.controlList.close();
+    }
+
+    ControlList getControlList() {
+        return this.controlList;
+    }
+
+    AbstractButton getDoneButton() {
+        return doneButton;
+    }
+}
index f6494eb84d606a88da2aacd6d92d07baa3cdcde1..b518d7dec6667eab7bdd3a7bf2de115cf523bd6b 100644 (file)
@@ -6,8 +6,8 @@ import net.minecraft.client.resources.I18n;
 class MaxYSettingSlider extends IntSettingSlider {
     private final int actualMinValue;
 
-    MaxYSettingSlider(int id, int x, int y, int width, int minValue, Setting<Integer> setting) {
-        super(id, x, y, width, minValue - 2, 127, I18n.format("bbor.options.maxY", "%s"), setting);
+    MaxYSettingSlider(int width, int minValue, Setting<Integer> setting) {
+        super(width, minValue - 2, 127, I18n.format("bbor.options.maxY", "%s"), setting);
         this.actualMinValue = minValue;
         this.setProgress(getSliderValue());
         this.addDisplayValue(-1, I18n.format("bbor.options.maxY.activated"));
diff --git a/src/main/java/com/irtimaled/bbor/client/gui/SearchField.java b/src/main/java/com/irtimaled/bbor/client/gui/SearchField.java
new file mode 100644 (file)
index 0000000..9da2581
--- /dev/null
@@ -0,0 +1,31 @@
+package com.irtimaled.bbor.client.gui;
+
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.GuiTextField;
+
+public class SearchField extends GuiTextField {
+    private final ControlList controlList;
+
+    SearchField(FontRenderer fontRenderer, int left, int top, int width, int height, ControlList controlList) {
+        super(0, fontRenderer, left, top, width, height);
+
+        this.controlList = controlList;
+        this.setTextAcceptHandler((id, text) -> this.controlList.filter(removeLeadingSpaces(text.toLowerCase())));
+        this.setTextFormatter((text, id) -> removeLeadingSpaces(text));
+        this.setFocused(true);
+        this.setCanLoseFocus(false);
+    }
+
+    private String removeLeadingSpaces(String text) {
+        return text.replaceFirst("^\\s++", "");
+    }
+
+    public void render(int mouseX, int mouseY) {
+        this.drawTextField(mouseX, mouseY, 0f);
+    }
+
+    @Override
+    public void setFocused(boolean ignored) {
+        super.setFocused(true);
+    }
+}
index 4a55d9128e6bd94d65591cfd36b6bd97bb8fa671..88fecf46891ef70688f1145afcf5d7d8a31adfd2 100644 (file)
 package com.irtimaled.bbor.client.gui;
 
 import com.irtimaled.bbor.client.ClientRenderer;
-import com.irtimaled.bbor.client.renderers.Renderer;
 import com.irtimaled.bbor.common.BoundingBoxType;
-import com.irtimaled.bbor.common.TypeHelper;
 import com.irtimaled.bbor.config.ConfigManager;
 import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.Gui;
 import net.minecraft.client.gui.GuiScreen;
-import net.minecraft.client.gui.IGuiEventListener;
-import net.minecraft.client.renderer.OpenGlHelper;
 import net.minecraft.client.resources.I18n;
-import org.lwjgl.opengl.GL11;
 
-import java.util.HashSet;
-import java.util.Set;
-
-public class SettingsScreen extends GuiScreen {
-    private static final int CONTROLS_WIDTH = 310;
-
-    private final GuiScreen lastScreen;
-    private final int tabIndex;
-
-    private String title;
-    private Set<IRenderableControl> controls = new HashSet<>();
-
-    SettingsScreen(GuiScreen lastScreen, int tabIndex) {
-        this.lastScreen = lastScreen;
-        this.tabIndex = tabIndex;
-    }
+public class SettingsScreen extends ListScreen {
+    private static final String pillagerOutpostVersionPattern = "(?:1\\.1[4-9]|1\\.[2-9][0-9]|18w(?:4[7-9]|5[0-9])|19w|2[0-9]w).*";
+    private static final String bastionRemnantVersionPattern = "(?:1\\.1[6-9]|1\\.[2-9][0-9]|20w(?:1[6-9]|[2-5][0-9])|2[1-9]w).*";
+    private static final String netherFossilVersionPattern = "(?:1\\.1[6-9]|1\\.[2-9][0-9]|20w(?:1[1-9]|[2-5][0-9])|2[1-9]w).*";
 
     public static void show() {
-        Minecraft.getInstance().displayGuiScreen(new SettingsScreen(null, 0));
-    }
-
-    private int getY(double row) {
-        return ((this.height / 6) - 12) + (int) ((row + 2.0) * 24.0);
-    }
-
-    private void addControl(IRenderableControl control) {
-        this.controls.add(control);
-        TypeHelper.doIfType(control, IGuiEventListener.class, this.children::add);
-    }
-
-    private void addTabs(String... labels) {
-        int columns = labels.length;
-        int column = 0;
-        int y = getY(-2);
-        for (String label : labels) {
-            final int index = column;
-            addControl(0, column, y, CONTROLS_WIDTH / columns,
-                    (id, x, y1, width) -> new AbstractButton(id, x, y, width, label, index != tabIndex) {
-                        @Override
-                        public void onPressed() {
-                            Minecraft.getInstance().displayGuiScreen(new SettingsScreen(lastScreen, index));
-                        }
-                    });
-            column++;
-        }
-
-        //done button
-        addControl(new AbstractButton(200, this.width / 2 - 100, getY(5.5), 200, I18n.format("gui.done")) {
-            @Override
-            public void onPressed() {
-                ConfigManager.saveConfig();
-                mc.displayGuiScreen(lastScreen);
-            }
-        });
-    }
-
-    private int getX(int width, int column, int offset) {
-        return ((this.width - CONTROLS_WIDTH) / 2) + (column * (width + offset));
-    }
-
-    private IControl addControl(int offset, int column, int y, int width, CreateControl createControl) {
-        int x = getX(width, column, offset);
-        int id = controls.size();
-        IControl control = createControl.create(id, x, y, width);
-        TypeHelper.doIfType(control, IRenderableControl.class, this::addControl);
-        return control;
+        Minecraft.getInstance().displayGuiScreen(new SettingsScreen(null));
     }
 
-    private void buildTab(int tabIndex, CreateControl... createControls) {
-        if (tabIndex != this.tabIndex) return;
-
-        int offset = 4;
-        int width = (CONTROLS_WIDTH - (2 * offset)) / 3;
-        int column = 0;
-        double row = -0.75;
-        for (CreateControl createControl : createControls) {
-            int y = getY(row);
-            IControl control = this.addControl(offset, column, y, width, createControl);
-            IRowHeight rowHeight = TypeHelper.as(control, IRowHeight.class);
-            if (rowHeight != null) {
-                if (column > 0) {
-                    row++;
-                    column = 0;
-                } else {
-                    row += rowHeight.getRowHeight();
-                }
-            } else {
-                column++;
-            }
-            if (column == 3) {
-                column = 0;
-                row++;
-            }
-        }
+    SettingsScreen(GuiScreen lastScreen) {
+        super(lastScreen);
     }
 
     @Override
-    protected void initGui() {
-        this.title = "Bounding Box Outline Reloaded";
-
-        this.controls = new HashSet<>();
-        this.addTabs(I18n.format("bbor.tabs.general"),
-                I18n.format("bbor.tabs.structures"),
-                I18n.format("bbor.tabs.villages"));
-
-        buildTab(0,
-                (id, x, y, width) -> new AbstractButton(id, x, y, width, I18n.format("bbor.options.active"), this.mc.world != null) {
-                    @Override
-                    public void onPressed() {
-                        ClientRenderer.toggleActive();
-                    }
-
-                    @Override
-                    protected int getState() {
-                        return enabled ? ClientRenderer.getActive() ? 2 : 1 : 0;
-                    }
-                },
-                (id, x, y, width) -> new BoolSettingButton(id, x, y, width, I18n.format("bbor.options.outerBoxOnly"), ConfigManager.outerBoxesOnly),
-                (id, x, y, width) -> new BoolSettingButton(id, x, y, width, I18n.format("bbor.options.fill"), ConfigManager.fill),
-
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.features.spawnChunks"), BoundingBoxType.WorldSpawn),
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.features.lazyChunks"), BoundingBoxType.LazySpawnChunks),
-                (id, x, y, width) -> new MaxYSettingSlider(id, x, y, width, 39, ConfigManager.worldSpawnMaxY),
-
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.features.slimeChunks"), BoundingBoxType.SlimeChunks),
-                (id, x, y, width) -> new MaxYSettingSlider(id, x, y, width, 39, ConfigManager.slimeChunkMaxY),
-                (id, x, y, width) -> (IRowHeight) () -> 0,
-
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.features.mobSpawners"), BoundingBoxType.MobSpawner),
-                (id, x, y, width) -> new BoolSettingButton(id, x, y, width, I18n.format("bbor.features.mobSpawners.spawnArea"), ConfigManager.renderMobSpawnerSpawnArea),
-                (id, x, y, width) -> new BoolSettingButton(id, x, y, width, I18n.format("bbor.features.mobSpawners.activationLines"), ConfigManager.renderMobSpawnerActivationLines),
-
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.features.spawningSpheres"), BoundingBoxType.AFKSphere),
-                (id, x, y, width) -> new BoolSettingButton(id, x, y, width, I18n.format("bbor.features.spawningSpheres.spawnableBlocks"), ConfigManager.renderAFKSpawnableBlocks),
-                (id, x, y, width) -> new IntSettingSlider(id, x, y, width, 1, 3, "bbor.options.distance", ConfigManager.afkSpawnableBlocksRenderDistance)
-                        .addDisplayValue(1, I18n.format("bbor.options.distance.nearest"))
-                        .addDisplayValue(2, I18n.format("bbor.options.distance.nearer"))
-                        .addDisplayValue(3, I18n.format("bbor.options.distance.normal")),
-
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.features.biomeBorders"), BoundingBoxType.BiomeBorder),
-                (id, x, y, width) -> new MaxYSettingSlider(id, x, y, width, 1, ConfigManager.biomeBordersMaxY),
-                (id, x, y, width) -> new IntSettingSlider(id, x, y, width, 1, 3, "bbor.options.distance", ConfigManager.biomeBordersRenderDistance)
-                        .addDisplayValue(1, I18n.format("bbor.options.distance.nearest"))
-                        .addDisplayValue(2, I18n.format("bbor.options.distance.nearer"))
-                        .addDisplayValue(3, I18n.format("bbor.options.distance.normal")));
-        buildTab(1,
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.structures.desertTemples"), BoundingBoxType.DesertTemple),
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.structures.jungleTemples"), BoundingBoxType.JungleTemple),
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.structures.witchHuts"), BoundingBoxType.WitchHut),
-
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.structures.mansions"), BoundingBoxType.Mansion),
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.structures.monuments"), BoundingBoxType.OceanMonument),
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.structures.igloos"), BoundingBoxType.Igloo),
-
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.structures.oceanRuins"), BoundingBoxType.OceanRuin),
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.structures.buriedTreasure"), BoundingBoxType.BuriedTreasure),
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.structures.shipwrecks"), BoundingBoxType.Shipwreck),
-
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.structures.strongholds"), BoundingBoxType.Stronghold),
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.structures.mineshafts"), BoundingBoxType.MineShaft),
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.structures.pillagerOutposts"), BoundingBoxType.PillagerOutpost, false),
-
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.structures.villages"), BoundingBoxType.Village),
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.structures.fortresses"), BoundingBoxType.NetherFortress),
-                (id, x, y, width) -> new BoundingBoxTypeButton(id, x, y, width, I18n.format("bbor.structures.endCities"), BoundingBoxType.EndCity));
-        buildTab(2,
-                (id, x, y, width) -> new BoolSettingButton(id, x, y, width, I18n.format("bbor.features.villageSpheres"), ConfigManager.drawVillageSpheres),
-                (id, x, y, width) -> new BoolSettingButton(id, x, y, width, I18n.format("bbor.features.villageSpheres.doorLines"), ConfigManager.drawVillageDoors),
-                (id, x, y, width) -> new BoolSettingButton(id, x, y, width, I18n.format("bbor.features.villageSpheres.golemSpawn"), ConfigManager.drawIronGolemSpawnArea),
-
-                (id, x, y, width) -> new IntSettingSlider(id, x, y, width, 1, 5, "bbor.features.villageSpheres.dotSize", ConfigManager.villageSphereDotSize),
-                (id, x, y, width) -> new IntSettingSlider(id, x, y, width, 1, 5, "bbor.features.villageSpheres.density", ConfigManager.villageSphereDensity)
-                        .addDisplayValue(1, I18n.format("bbor.features.villageSpheres.density.fewest"))
-                        .addDisplayValue(2, I18n.format("bbor.features.villageSpheres.density.fewer"))
-                        .addDisplayValue(3, I18n.format("bbor.features.villageSpheres.density.normal"))
-                        .addDisplayValue(4, I18n.format("bbor.features.villageSpheres.density.more"))
-                        .addDisplayValue(5, I18n.format("bbor.features.villageSpheres.density.most")));
-    }
-
-    private void drawScreen(int top, int bottom) {
-        this.mc.getTextureManager().bindTexture(Gui.OPTIONS_BACKGROUND);
-
-        GL11.glDisable(GL11.GL_LIGHTING);
-        GL11.glDisable(GL11.GL_FOG);
-        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
-
-        Renderer.startTextured()
-                .setColor(32, 32, 32)
-                .setAlpha(255)
-                .addPoint(0, bottom, 0, 0, bottom / 32.0F)
-                .addPoint(this.width, bottom, 0, this.width / 32.0F, bottom / 32.0F)
-                .addPoint(this.width, top, 0, this.width / 32.0F, top / 32.0F)
-                .addPoint(0, top, 0, 0, top / 32.0F)
-                .render();
-
-        GL11.glDisable(GL11.GL_DEPTH_TEST);
-        GL11.glEnable(GL11.GL_BLEND);
-        OpenGlHelper.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ZERO, GL11.GL_ONE);
-
-        GL11.glDisable(GL11.GL_ALPHA_TEST);
-        GL11.glShadeModel(7425);
-        GL11.glDisable(GL11.GL_TEXTURE_2D);
-
-        Renderer.startTextured()
-                .setAlpha(0)
-                .addPoint(0, top + 4, 0, 0, 1)
-                .addPoint(this.width, top + 4, 0, 1, 1)
-                .setAlpha(255)
-                .addPoint(this.width, top, 0, 1, 0)
-                .addPoint(0, top, 0, 0, 0)
-                .render();
-
-        Renderer.startTextured()
-                .setAlpha(255)
-                .addPoint(0, bottom, 0, 0, 1)
-                .addPoint(this.width, bottom, 0, 1, 1)
-                .setAlpha(0)
-                .addPoint(this.width, bottom - 4, 0, 1, 0)
-                .addPoint(0, bottom - 4, 0, 0, 0)
-                .render();
-
-        GL11.glEnable(GL11.GL_TEXTURE_2D);
-        GL11.glShadeModel(7424);
-        GL11.glEnable(GL11.GL_ALPHA_TEST);
-        OpenGlHelper.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO);
-        GL11.glDisable(GL11.GL_BLEND);
+    protected void onDoneClicked() {
+        ConfigManager.saveConfig();
+        super.onDoneClicked();
     }
 
     @Override
-    public void render(int mouseX, int mouseY, float unknown) {
-        if (this.mc.world == null) {
-            this.drawDefaultBackground();
-            this.drawScreen(getY(-1), getY(5.5) - 4);
-        }
-        this.drawCenteredString(this.fontRenderer, this.title, this.width / 2, 15, 16777215);
-        for (IRenderableControl control : controls) {
-            control.render(mouseX, mouseY);
-        }
+    protected void setup() {
+        String version = this.mc.getVersion();
+        ControlList controlList = this.getControlList();
+        if (this.mc.world != null) controlList.setTransparentBackground();
+
+        controlList
+                .section(null,
+                        (x, width) -> new BoolButton(width, I18n.format("bbor.options.active"), this.mc.world != null) {
+                            @Override
+                            public void onPressed() {
+                                ClientRenderer.toggleActive();
+                            }
+
+                            @Override
+                            protected boolean getValue() {
+                                return ClientRenderer.getActive();
+                            }
+                        },
+                        (x, width) -> new BoolSettingButton(width, I18n.format("bbor.options.outerBoxOnly"), ConfigManager.outerBoxesOnly),
+                        (x, width) -> new BoolSettingButton(width, I18n.format("bbor.options.fill"), ConfigManager.fill))
+                .section(I18n.format("bbor.features.spawnChunks"),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.features.spawnChunks"), BoundingBoxType.WorldSpawn),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.features.lazyChunks"), BoundingBoxType.LazySpawnChunks),
+                        (x, width) -> new MaxYSettingSlider(width, 39, ConfigManager.worldSpawnMaxY))
+                .section(I18n.format("bbor.features.slimeChunks"),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.features.slimeChunks"), BoundingBoxType.SlimeChunks),
+                        (x, width) -> new MaxYSettingSlider(width, 39, ConfigManager.slimeChunkMaxY))
+                .section(I18n.format("bbor.features.biomeBorders"),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.features.biomeBorders"), BoundingBoxType.BiomeBorder),
+                        (x, width) -> new MaxYSettingSlider(width, 1, ConfigManager.biomeBordersMaxY),
+                        (x, width) -> new IntSettingSlider(width, 1, 3, "bbor.options.distance", ConfigManager.biomeBordersRenderDistance)
+                                .addDisplayValue(1, I18n.format("bbor.options.distance.nearest"))
+                                .addDisplayValue(2, I18n.format("bbor.options.distance.nearer"))
+                                .addDisplayValue(3, I18n.format("bbor.options.distance.normal")))
+                .section(I18n.format("bbor.features.mobSpawners"),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.features.mobSpawners"), BoundingBoxType.MobSpawner),
+                        (x, width) -> new BoolSettingButton(width, I18n.format("bbor.features.mobSpawners.spawnArea"), ConfigManager.renderMobSpawnerSpawnArea),
+                        (x, width) -> new BoolSettingButton(width, I18n.format("bbor.features.mobSpawners.activationLines"), ConfigManager.renderMobSpawnerActivationLines))
+                .section(I18n.format("bbor.features.spawningSpheres"),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.features.spawningSpheres"), BoundingBoxType.AFKSphere),
+                        (x, width) -> new BoolSettingButton(width, I18n.format("bbor.features.spawningSpheres.spawnableBlocks"), ConfigManager.renderAFKSpawnableBlocks),
+                        (x, width) -> new IntSettingSlider(width, 1, 3, "bbor.options.distance", ConfigManager.afkSpawnableBlocksRenderDistance)
+                                .addDisplayValue(1, I18n.format("bbor.options.distance.nearest"))
+                                .addDisplayValue(2, I18n.format("bbor.options.distance.nearer"))
+                                .addDisplayValue(3, I18n.format("bbor.options.distance.normal")))
+                .section(I18n.format("bbor.tabs.structures"),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.structures.desertTemples"), BoundingBoxType.DesertTemple),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.structures.jungleTemples"), BoundingBoxType.JungleTemple),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.structures.witchHuts"), BoundingBoxType.WitchHut),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.structures.mansions"), BoundingBoxType.Mansion),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.structures.monuments"), BoundingBoxType.OceanMonument),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.structures.igloos"), BoundingBoxType.Igloo),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.structures.oceanRuins"), BoundingBoxType.OceanRuin),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.structures.buriedTreasure"), BoundingBoxType.BuriedTreasure),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.structures.shipwrecks"), BoundingBoxType.Shipwreck),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.structures.strongholds"), BoundingBoxType.Stronghold),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.structures.mineshafts"), BoundingBoxType.MineShaft),
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.structures.villages"), BoundingBoxType.Village),
+                        (x, width) -> version.matches(pillagerOutpostVersionPattern) ? new BoundingBoxTypeButton(width, I18n.format("bbor.structures.pillagerOutposts"), BoundingBoxType.PillagerOutpost) : null,
+                        (x, width) -> version.matches(bastionRemnantVersionPattern) ? new BoundingBoxTypeButton(width, I18n.format("bbor.structures.ruinedPortal"), BoundingBoxType.RuinedPortal) : null,
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.structures.fortresses"), BoundingBoxType.NetherFortress),
+                        (x, width) -> version.matches(netherFossilVersionPattern) ? new BoundingBoxTypeButton(width, I18n.format("bbor.structures.netherFossils"), BoundingBoxType.NetherFossil) : null,
+                        (x, width) -> version.matches(bastionRemnantVersionPattern) ? new BoundingBoxTypeButton(width, I18n.format("bbor.structures.bastionRemnants"), BoundingBoxType.BastionRemnant) : null,
+                        (x, width) -> new BoundingBoxTypeButton(width, I18n.format("bbor.structures.endCities"), BoundingBoxType.EndCity))
+                .section(I18n.format("bbor.tabs.villages"),
+                        (x, width) -> new BoolSettingButton(width, I18n.format("bbor.features.villageSpheres"), ConfigManager.drawVillageSpheres),
+                        (x, width) -> new BoolSettingButton(width, I18n.format("bbor.features.villageSpheres.doorLines"), ConfigManager.drawVillageDoors),
+                        (x, width) -> new BoolSettingButton(width, I18n.format("bbor.features.villageSpheres.golemSpawn"), ConfigManager.drawIronGolemSpawnArea),
+                        (x, width) -> new IntSettingSlider(width, 1, 5, "bbor.features.villageSpheres.dotSize", ConfigManager.villageSphereDotSize),
+                        (x, width) -> new IntSettingSlider(width, 1, 5, "bbor.features.villageSpheres.density", ConfigManager.villageSphereDensity)
+                                .addDisplayValue(1, I18n.format("bbor.features.villageSpheres.density.fewest"))
+                                .addDisplayValue(2, I18n.format("bbor.features.villageSpheres.density.fewer"))
+                                .addDisplayValue(3, I18n.format("bbor.features.villageSpheres.density.normal"))
+                                .addDisplayValue(4, I18n.format("bbor.features.villageSpheres.density.more"))
+                                .addDisplayValue(5, I18n.format("bbor.features.villageSpheres.density.most")));
     }
 }
index d9dd00323d80dd643b85dd322b4460b7a1a8b35c..c0894df6fbe564d43607cfe9335a2a87e9014f50 100644 (file)
@@ -6,9 +6,9 @@ import net.minecraft.client.gui.GuiScreen;
 public class SettingsScreenButton extends AbstractButton {
     private final SettingsScreen screen;
 
-    public SettingsScreenButton(int id, int x, int y, int width, String label, GuiScreen lastScreen) {
-        super(id, x, y, width, label);
-        screen = new SettingsScreen(lastScreen, 0);
+    public SettingsScreenButton(int x, int y, int width, String label, GuiScreen lastScreen) {
+        super(x, y, width, label);
+        screen = new SettingsScreen(lastScreen);
     }
 
     @Override
index a8906a260889c005a1011c600107fc95768eeefc..dc43d03f080f7146ab941799ecd40aa2b0cb6e4e 100644 (file)
@@ -39,7 +39,7 @@ public class Renderer {
         bufferBuilder.begin(glMode, vertexFormat);
     }
 
-    Renderer setColor(Color color) {
+    public Renderer setColor(Color color) {
         return setColor(color.getRed(), color.getGreen(), color.getBlue())
                 .setAlpha(color.getAlpha());
     }
@@ -57,8 +57,7 @@ public class Renderer {
     }
 
     Renderer addPoint(OffsetPoint point) {
-        addPoint(point.getX(), point.getY(), point.getZ());
-        return this;
+        return addPoint(point.getX(), point.getY(), point.getZ());
     }
 
     Renderer addPoint(double x, double y, double z) {
index cba5640805793e985adeb12ad300236f977e1f3a..f72c54f7dee3d4935411bfeb132df207d6fd7c32 100644 (file)
@@ -20,6 +20,6 @@ public class MixinGuiOptions extends GuiScreen {
             if (button.y >= top && button.y < bottom)
                 button.y -= 12;
         }
-        this.addButton(new SettingsScreenButton(199, this.width / 2 - 155, top + 84, 150, "BBOR", this));
+        this.addButton(new SettingsScreenButton(this.width / 2 - 155, top + 84, 150, "BBOR", this));
     }
 }
index 08be1a8b22449b4a8187c1342d2b2266c61a5270..4043f9a19945bb1127b2d969c69324071a5f0e2b 100644 (file)
@@ -1,7 +1,6 @@
 {
   "bbor.key.toggleActive": "Toggle Active",
 
-  "bbor.tabs.general": "General",
   "bbor.tabs.structures": "Structures",
   "bbor.tabs.villages": "Villages",
 
@@ -28,7 +27,6 @@
   "bbor.features.spawningSpheres": "Spawning Spheres",
   "bbor.features.spawningSpheres.spawnableBlocks": "Spawnable Blocks",
   "bbor.features.biomeBorders": "Biome Borders",
-  "bbor.features.biomeBorders.onlyThisBiome": "Only This Biome",
 
   "bbor.structures.desertTemples": "Desert Temples",
   "bbor.structures.jungleTemples": "Jungle Temples",