From 60f1c29872465a25be4f2c4ca8c5eb1abf69f988 Mon Sep 17 00:00:00 2001 From: nextdaydelivery <79922345+nxtdaydelivery@users.noreply.github.com> Date: Sun, 1 May 2022 12:36:32 +0100 Subject: config elements --- .../io/polyfrost/oneconfig/gui/OneConfigGui.java | 1 + .../oneconfig/gui/elements/TextInputField.java | 58 ++++++- .../gui/elements/config/ConfigDualOption.java | 6 +- .../gui/elements/config/ConfigSlider.java | 178 +++++++++++++++++++++ 4 files changed, 232 insertions(+), 11 deletions(-) create mode 100644 src/main/java/io/polyfrost/oneconfig/gui/elements/config/ConfigSlider.java (limited to 'src/main/java/io/polyfrost/oneconfig/gui') diff --git a/src/main/java/io/polyfrost/oneconfig/gui/OneConfigGui.java b/src/main/java/io/polyfrost/oneconfig/gui/OneConfigGui.java index 0a4acd6..77d30bd 100644 --- a/src/main/java/io/polyfrost/oneconfig/gui/OneConfigGui.java +++ b/src/main/java/io/polyfrost/oneconfig/gui/OneConfigGui.java @@ -93,6 +93,7 @@ public class OneConfigGui extends GuiScreen { } public void openPage(@NotNull Page page) { + if(page == currentPage) return; currentPage.finishUpAndClose(); if (prevPage == null) { prevPage = currentPage; diff --git a/src/main/java/io/polyfrost/oneconfig/gui/elements/TextInputField.java b/src/main/java/io/polyfrost/oneconfig/gui/elements/TextInputField.java index 8f7f77c..081c99b 100644 --- a/src/main/java/io/polyfrost/oneconfig/gui/elements/TextInputField.java +++ b/src/main/java/io/polyfrost/oneconfig/gui/elements/TextInputField.java @@ -28,6 +28,9 @@ public class TextInputField extends BasicElement { protected long vg; protected int prevCaret = 0; protected boolean isDoubleClick = false; + protected boolean onlyNums = false; + protected boolean errored = false; + protected boolean centered = false; public TextInputField(int width, int height, String defaultText, boolean multiLine, boolean password) { super(width, height, false); @@ -37,6 +40,10 @@ public class TextInputField extends BasicElement { this.input = ""; } + public void onlyAcceptNumbers(boolean state) { + onlyNums = state; + } + public void setInput(String input) { this.input = input; } @@ -53,18 +60,32 @@ public class TextInputField extends BasicElement { return password; } + public void setErrored(boolean errored) { + this.errored = errored; + } + + public void setCentered(boolean centered) { + this.centered = centered; + } + + public boolean isErrored() { + return errored; + } + @Override public void draw(long vg, int x, int y) { this.x = x; this.y = y; this.vg = vg; try { - RenderManager.drawHollowRoundRect(vg, x, y, width, height, OneConfigConfig.GRAY_700, 12f, 2f); + int colorOutline = errored ? OneConfigConfig.ERROR_700 : OneConfigConfig.GRAY_700; + RenderManager.drawHollowRoundRect(vg, x, y, width, height, colorOutline, 12f, 2f); super.update(x, y); if (Mouse.isButtonDown(0) && !InputUtils.isAreaHovered(x - 40, y - 20, width + 90, height + 20)) { toggled = false; } int color = toggled ? OneConfigConfig.WHITE : OneConfigConfig.WHITE_60; + if(!toggled) caretPos = input.length(); float width; StringBuilder s = new StringBuilder(); if (!password) { @@ -102,6 +123,7 @@ public class TextInputField extends BasicElement { } } } + float halfTextWidth = this.getTextWidth(vg, input) / 2f; if (start != 0f && end != 0f && toggled) { RenderManager.drawRect(vg, start, y + height / 2f - 10, end, 20, OneConfigConfig.GRAY_300); } @@ -109,11 +131,13 @@ public class TextInputField extends BasicElement { if (Mouse.isButtonDown(0) && !isDoubleClick) { caretPos = calculatePos(Mouse.getX()); if (caretPos > prevCaret) { - start = x + 12 + this.getTextWidth(vg, input.substring(0, prevCaret)); + if(!centered) start = x + 12 + this.getTextWidth(vg, input.substring(0, prevCaret)); + else start = x + this.width / 2f - halfTextWidth + this.getTextWidth(vg, input.substring(0, prevCaret)); end = this.getTextWidth(vg, input.substring(prevCaret, caretPos)); selectedText = input.substring(prevCaret, caretPos); } else { - start = x + 12 + this.getTextWidth(vg, input.substring(0, prevCaret)); + if(!centered) start = x + 12 + this.getTextWidth(vg, input.substring(0, prevCaret)); + else start = x + this.width / 2f - halfTextWidth + this.getTextWidth(vg, input.substring(0, prevCaret)); end = -this.getTextWidth(vg, input.substring(caretPos, prevCaret)); selectedText = input.substring(caretPos, prevCaret); } @@ -122,16 +146,28 @@ public class TextInputField extends BasicElement { if (toggled) { - RenderManager.drawLine(vg, x + width + 12, (float) y + height / 2f - 10, x + width + 12, (float) y + height / 2f + 10, 1, OneConfigConfig.WHITE); + if(!centered) { + RenderManager.drawLine(vg, x + width + 12, (float) y + height / 2f - 10, x + width + 12, (float) y + height / 2f + 10, 1, OneConfigConfig.WHITE); + } else { + RenderManager.drawLine(vg, x + this.width / 2f - halfTextWidth + width, (float) y + height / 2f - 10, x + this.width / 2f - halfTextWidth + width, (float) y + height / 2f + 10, 1, OneConfigConfig.WHITE); + } } if (input.equals("")) { - RenderManager.drawString(vg, defaultText, x + 12, y + height / 2f + 1, color, 14f, Fonts.INTER_REGULAR); + if(!centered) { + RenderManager.drawString(vg, defaultText, x + 12, y + height / 2f + 1, color, 14f, Fonts.INTER_REGULAR); + } else { + RenderManager.drawString(vg, defaultText, x + this.width / 2f - halfTextWidth, y + height / 2f + 1, color, 14f, Fonts.INTER_REGULAR); + } } if (!password) { - RenderManager.drawString(vg, input, x + 12, y + height / 2f + 1, color, 14f, Fonts.INTER_REGULAR); + if(!centered) { + RenderManager.drawString(vg, input, x + 12, y + height / 2f + 1, color, 14f, Fonts.INTER_REGULAR); + } else { + RenderManager.drawString(vg, input, x + this.width / 2f - halfTextWidth, y + height / 2f + 1, color, 14f, Fonts.INTER_REGULAR); + } } else { RenderManager.drawString(vg, s.toString(), x + 12, y + height / 2f + 1, color, 14f, Fonts.INTER_REGULAR); } @@ -178,7 +214,7 @@ public class TextInputField extends BasicElement { if (GuiScreen.isKeyComboCtrlA(key)) { prevCaret = 0; caretPos = input.length(); - start = x + 12; + start = !centered ? x + 12 : x + this.width / 2f - this.getTextWidth(vg, input) / 2f; selectedText = input; end = this.getTextWidth(vg, input); return; @@ -222,6 +258,7 @@ public class TextInputField extends BasicElement { return; } if (key == Keyboard.KEY_TAB) { + if(onlyNums) return; input += " "; caretPos += 4; return; @@ -282,6 +319,9 @@ public class TextInputField extends BasicElement { if (key == Keyboard.KEY_LCONTROL || key == Keyboard.KEY_RCONTROL || key == Keyboard.KEY_LMENU || key == Keyboard.KEY_RMENU || key == Keyboard.KEY_LMETA || key == Keyboard.KEY_RMETA || key == Keyboard.KEY_LSHIFT || key == Keyboard.KEY_RSHIFT || key == Keyboard.KEY_RETURN || key == Keyboard.KEY_CAPITAL || key == 221 || key == Keyboard.KEY_HOME) { return; } + if(onlyNums) { + if(!Character.isDigit(c) && key != 52) return; + } if (!Character.isDefined(key)) return; if (!Character.isDefined(c)) return; if(GuiScreen.isCtrlKeyDown()) return; @@ -329,11 +369,13 @@ public class TextInputField extends BasicElement { caretPos = input.indexOf(' ', caretPos); if(caretPos == -1) caretPos = input.length(); selectedText = input.substring(prevCaret, caretPos); - start = x + 12 + this.getTextWidth(vg, input.substring(0, prevCaret)); + if(!centered) start = x + 12 + this.getTextWidth(vg, input.substring(0, prevCaret)); + else start = x + this.width / 2f - this.getTextWidth(vg, input) / 2f + this.getTextWidth(vg, input.substring(0, prevCaret)); end = this.getTextWidth(vg, input.substring(prevCaret, caretPos)); } private int calculatePos(int pos) { + if(centered) pos -= 12; String s1 = ""; int i; for (char c : input.toCharArray()) { diff --git a/src/main/java/io/polyfrost/oneconfig/gui/elements/config/ConfigDualOption.java b/src/main/java/io/polyfrost/oneconfig/gui/elements/config/ConfigDualOption.java index 705ab1a..3e90e57 100644 --- a/src/main/java/io/polyfrost/oneconfig/gui/elements/config/ConfigDualOption.java +++ b/src/main/java/io/polyfrost/oneconfig/gui/elements/config/ConfigDualOption.java @@ -13,10 +13,10 @@ public class ConfigDualOption extends BasicOption { private float percentMove = 0f; private final String left, right; - public ConfigDualOption(Field field, String name, int size, String left, String right) { + public ConfigDualOption(Field field, String name, int size, String[] options) { super(field, name, size); - this.left = left; - this.right = right; + this.left = options[0]; + this.right = options[1]; } diff --git a/src/main/java/io/polyfrost/oneconfig/gui/elements/config/ConfigSlider.java b/src/main/java/io/polyfrost/oneconfig/gui/elements/config/ConfigSlider.java new file mode 100644 index 0000000..54df53e --- /dev/null +++ b/src/main/java/io/polyfrost/oneconfig/gui/elements/config/ConfigSlider.java @@ -0,0 +1,178 @@ +package io.polyfrost.oneconfig.gui.elements.config; + +import io.polyfrost.oneconfig.config.OneConfigConfig; +import io.polyfrost.oneconfig.config.interfaces.BasicOption; +import io.polyfrost.oneconfig.gui.elements.BasicElement; +import io.polyfrost.oneconfig.gui.elements.TextInputField; +import io.polyfrost.oneconfig.lwjgl.RenderManager; +import io.polyfrost.oneconfig.lwjgl.font.Fonts; +import io.polyfrost.oneconfig.utils.ColorUtils; +import io.polyfrost.oneconfig.utils.InputUtils; +import io.polyfrost.oneconfig.utils.MathUtils; +import org.lwjgl.input.Mouse; +import org.lwjgl.nanovg.NanoVG; + +import java.lang.reflect.Field; + +public class ConfigSlider extends BasicOption { + private final BasicElement slideYBoi = new BasicElement(24, 24, false); + private final TextInputField inputField = new TextInputField(84, 24, "", false, false); + private final BasicElement upArrow = new BasicElement(12, 14, false); + private final BasicElement downArrow = new BasicElement(12, 14, false); + private final float min, max; + private final int step; + private float current; + private int colorTop, colorBottom; + + public ConfigSlider(Field field, String name, int size, float min, float max, int step) { + super(field, name, size); + this.min = min; + this.max = max; + this.step = step - 1; // it adds one more step than actual + slideYBoi.setCustomHitbox(28, 8); + inputField.onlyAcceptNumbers(true); + inputField.setCentered(true); + try { + inputField.setInput(String.valueOf(get())); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + @Override + public int getHeight() { + return 32; + } + + @Override + public void draw(long vg, int x, int y) { + RenderManager.drawString(vg, name, x, y + 15, OneConfigConfig.WHITE_90, 18f, Fonts.INTER_MEDIUM); + RenderManager.drawRoundedRect(vg, x + 352, y + 13, 512, 6, OneConfigConfig.GRAY_300, 4f); + slideYBoi.update(x + 340 + (int) (current * 512), y + 4); + if(step != 0) { + for(float i = 0; i <= 1.005f; i += 1f / step) { // sometimes it's just more than 1, so we add a little + int color = current > i ? OneConfigConfig.BLUE_500 : OneConfigConfig.GRAY_300; + RenderManager.drawRoundedRect(vg, x + 351 + (int) (i * 512), y + 9, 4, 14, color, 2f); + } + } + RenderManager.drawRoundedRect(vg, x + 352, y + 13, (int) (current * 512), 6, OneConfigConfig.BLUE_500, 4f); + if(step == 0) RenderManager.drawRoundedRect(vg, x + 340 + (int) (current * 512), y + 4, 24, 24, OneConfigConfig.WHITE, 12f); + else RenderManager.drawRoundedRect(vg, x + 346 + (int) (current * 512), y + 4, 8, 24, OneConfigConfig.WHITE, 4f); + + + int mouseX = InputUtils.mouseX() - (x + 352); + if(InputUtils.isAreaClicked(x + 332, y + 9, 542, 10) && !slideYBoi.isHovered()) { + if(step == 0) { + current = MathUtils.clamp(mouseX / 512f); + } else current = MathUtils.clamp(toNearestStep(mouseX / 512f)); + } + if(slideYBoi.isHovered() && Mouse.isButtonDown(0)) { + if(step == 0) { + current = MathUtils.clamp(mouseX / 512f); + } else current = MathUtils.clamp(toNearestStep(mouseX / 512f)); + } + float currentAsNum = current * (max - min) + min; + + if(!inputField.isToggled()) inputField.setInput(String.format("%.01f", currentAsNum)); + inputField.setErrored(false); + if(inputField.isToggled()) { + try { + float input = Float.parseFloat(inputField.getInput()); + if(input < min) { + inputField.setErrored(true); + input = min; + } + if(input > max) { + inputField.setErrored(true); + input = max; + } + if(step == 0) { + current = MathUtils.clamp((input - min) / (max - min)); + } else { + current = toNearestStep(MathUtils.clamp((input - min) / (max - min))); + } + } catch (NumberFormatException ignored) { + inputField.setErrored(true); + } + } + inputField.draw(vg, x + 892, y); + + RenderManager.drawRoundedRect(vg, x + 980, y, 12, 28, OneConfigConfig.GRAY_500, 6f); + upArrow.update(x + 980, y); + downArrow.update(x + 980, y + 14); + if(current == 1f) colorTop = OneConfigConfig.GRAY_500_80; + if(current == 0f) colorBottom = OneConfigConfig.GRAY_500_80; + colorTop = ColorUtils.getColor(colorTop, 2, upArrow.isHovered(), upArrow.isClicked()); + colorBottom = ColorUtils.getColor(colorBottom, 2, downArrow.isHovered(), downArrow.isClicked()); + if(upArrow.isClicked()) { + if(step == 0) { + currentAsNum += 1; + current = MathUtils.clamp((currentAsNum - min) / (max - min)); + } else { + for(float i1 = 0f; i1 <= 1f; i1 += 1f / step) { + if(i1 > current) { + current = i1; + break; + } + } + } + } + if(downArrow.isClicked()) { + if(step == 0) { + currentAsNum -= 1; + current = MathUtils.clamp((currentAsNum - min) / (max - min)); + } else { + for(float i1 = 1f; i1 >= 0f; i1 -= 1f / step) { + if(i1 < current) { + current = i1; + break; + } + } + } + } + if(current == 1f) NanoVG.nvgGlobalAlpha(vg, 0.3f); + RenderManager.drawRoundedRectVaried(vg, x + 980, y, 12, 14, colorTop,6f, 6f, 0f, 0f); + RenderManager.drawImage(vg, "/assets/oneconfig/textures/smallUpArrow.png", x + 981, y + 2, 10, 10); + if(current == 1f) NanoVG.nvgGlobalAlpha(vg, 1f); + + if(current == 0f) NanoVG.nvgGlobalAlpha(vg, 0.3f); + RenderManager.drawRoundedRectVaried(vg, x + 980, y + 14, 12, 14, colorBottom,0f, 0f, 6f, 6f); + NanoVG.nvgTranslate(vg, x + 991, y + 25); + NanoVG.nvgRotate(vg, (float) Math.toRadians(180)); + RenderManager.drawImage(vg, "/assets/oneconfig/textures/smallUpArrow.png", 0, 0, 10, 10); + NanoVG.nvgResetTransform(vg); + NanoVG.nvgGlobalAlpha(vg, 1f); + } + + private float toNearestStep(float input) { + float stepF = 1f / step; + float stepAbove = 1f, stepBelow = 0f; + for(float a = 0f; a <= 1f; a += stepF) { + if(a > input) { + stepAbove = a; + break; + } + } + for(float a = 1f; a >= 0f; a -= stepF) { + if(a <= input) { + stepBelow = a; + break; + } + } + if(stepAbove - input > input - stepBelow) { + return stepBelow; + } else { + return stepAbove; + } + } + + @Override + public boolean hasHalfSize() { + return false; + } + + @Override + public void keyTyped(char key, int keyCode) { + inputField.keyTyped(key, keyCode); + } +} -- cgit