From a0ff501947a84b268e099524a06b56a6b900dad2 Mon Sep 17 00:00:00 2001 From: DeDiamondPro <67508414+DeDiamondPro@users.noreply.github.com> Date: Tue, 3 May 2022 18:25:32 +0200 Subject: move to cc.polyfrost --- .../gui/elements/config/ConfigCheckbox.java | 61 +++++++ .../gui/elements/config/ConfigColorElement.java | 115 +++++++++++++ .../gui/elements/config/ConfigDropdown.java | 167 +++++++++++++++++++ .../gui/elements/config/ConfigDualOption.java | 53 ++++++ .../gui/elements/config/ConfigPageButton.java | 57 +++++++ .../gui/elements/config/ConfigSlider.java | 184 +++++++++++++++++++++ .../gui/elements/config/ConfigSwitch.java | 54 ++++++ .../gui/elements/config/ConfigTextBox.java | 61 +++++++ .../gui/elements/config/ConfigUniSelector.java | 78 +++++++++ 9 files changed, 830 insertions(+) create mode 100644 src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigCheckbox.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigColorElement.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigDropdown.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigDualOption.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigPageButton.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigSlider.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigSwitch.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigTextBox.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigUniSelector.java (limited to 'src/main/java/cc/polyfrost/oneconfig/gui/elements/config') diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigCheckbox.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigCheckbox.java new file mode 100644 index 0000000..990ce07 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigCheckbox.java @@ -0,0 +1,61 @@ +package cc.polyfrost.oneconfig.gui.elements.config; + +import cc.polyfrost.oneconfig.config.OneConfigConfig; +import cc.polyfrost.oneconfig.config.interfaces.BasicOption; +import cc.polyfrost.oneconfig.lwjgl.RenderManager; +import cc.polyfrost.oneconfig.lwjgl.font.Fonts; +import cc.polyfrost.oneconfig.lwjgl.image.Images; +import cc.polyfrost.oneconfig.utils.ColorUtils; +import cc.polyfrost.oneconfig.utils.InputUtils; +import cc.polyfrost.oneconfig.utils.MathUtils; + +import java.awt.*; +import java.lang.reflect.Field; + +public class ConfigCheckbox extends BasicOption { + private int color; + private float percentOn = 0f; + + public ConfigCheckbox(Field field, String name, int size) { + super(field, name, size); + } + + @Override + public void draw(long vg, int x, int y) { + boolean toggled = false; + try { + toggled = (boolean) get(); + } catch (IllegalAccessException ignored) { + } + boolean hover = InputUtils.isAreaHovered(x, y + 4, 24, 24); + + boolean clicked = InputUtils.isClicked() && hover; + if (clicked) { + toggled = !toggled; + try { + set(toggled); + } catch (IllegalAccessException e) { + System.err.println("failed to write config value: class=" + this + " fieldWatching=" + field + " valueWrite=" + toggled); + e.printStackTrace(); + } + } + if (percentOn != 1f) { // performance + RenderManager.drawRoundedRect(vg, x, y + 4, 24, 24, color, 6f); + RenderManager.drawHollowRoundRect(vg, x, y + 4, 23.5f, 23.5f, OneConfigConfig.GRAY_300, 6f, 1f); // the 0.5f is to make it look better ok + } + color = ColorUtils.smoothColor(color, OneConfigConfig.GRAY_600, OneConfigConfig.GRAY_400, hover, 40f); + RenderManager.drawString(vg, name, x + 32, y + 17, OneConfigConfig.WHITE_90, 14f, Fonts.INTER_MEDIUM); + percentOn = MathUtils.clamp(MathUtils.easeOut(percentOn, toggled ? 1f : 0f, 5f)); + if (percentOn == 0f) return; + if (percentOn != 1f) { + RenderManager.drawImage(vg, Images.CHECKMARK, x, y + 4, 24, 24, new Color(1f, 1f, 1f, percentOn).getRGB()); + } else { // performance, that color could cause havoc am I right definitely + RenderManager.drawImage(vg, Images.CHECKMARK, x, y + 4, 24, 24); + } + } + + @Override + public int getHeight() { + return 32; + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigColorElement.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigColorElement.java new file mode 100644 index 0000000..2c89133 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigColorElement.java @@ -0,0 +1,115 @@ +package cc.polyfrost.oneconfig.gui.elements.config; + +import cc.polyfrost.oneconfig.config.OneConfigConfig; +import cc.polyfrost.oneconfig.config.interfaces.BasicOption; +import cc.polyfrost.oneconfig.gui.OneConfigGui; +import cc.polyfrost.oneconfig.gui.elements.BasicElement; +import cc.polyfrost.oneconfig.gui.elements.ColorSelector; +import cc.polyfrost.oneconfig.gui.elements.TextInputField; +import cc.polyfrost.oneconfig.lwjgl.RenderManager; +import cc.polyfrost.oneconfig.lwjgl.font.Fonts; +import cc.polyfrost.oneconfig.lwjgl.image.Images; +import cc.polyfrost.oneconfig.utils.InputUtils; + +import java.awt.*; +import java.lang.reflect.Field; + +public class ConfigColorElement extends BasicOption { + private float alpha; + private Color color = Color.BLUE; + private String hex; + + private final TextInputField hexField = new TextInputField(104, 32, "", false, false); + private final TextInputField alphaField = new TextInputField(72, 32, "", false, false); + private final BasicElement element = new BasicElement(64, 32, false); + + public ConfigColorElement(Field field, String name, int size) { + super(field, name, size); + hexField.setCentered(true); + alphaField.setCentered(true); + alphaField.onlyAcceptNumbers(true); + String buf = Integer.toHexString(color.getRGB()); + hex = "#"+buf.substring(buf.length()-6); + } + + @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); + hexField.draw(vg, x + 240, y); + + if (!alphaField.isToggled()) alphaField.setInput(String.format("%.01f", alpha * 100f) + "%"); + alphaField.setErrored(false); + if(alphaField.isToggled()) { + try { + float input = Float.parseFloat(alphaField.getInput()); + if (input < 0f) { + alphaField.setErrored(true); + input = 100f; + } + if (input > 100f) { + alphaField.setErrored(true); + input = 100f; + } + alpha = input / 100f; + } catch (NumberFormatException e) { + alphaField.setErrored(true); + } + } + alphaField.draw(vg, x + 352, y); + + + + if (!hexField.isToggled()) hexField.setInput(hex); + hexField.setErrored(false); + if(hexField.isToggled()) { + try { + color = HexToColor(hexField.getInput()); + String buf = Integer.toHexString(color.getRGB()); + hex = "#"+buf.substring(buf.length()-6); + } catch (NumberFormatException e) { + hexField.setErrored(true); + } + } + hexField.draw(vg, x + 352, y); + + element.update(x + 432, y); + RenderManager.drawRoundedRect(vg, x + 432, y, 64, 32, OneConfigConfig.GRAY_300, 12f); + RenderManager.drawImage(vg, Images.COLOR_BASE, x + 948, y + 4, 56, 24, color.getRGB()); + if(element.isClicked() && !element.isToggled()) { + OneConfigGui.INSTANCE.initColorSelector(new ColorSelector(color, InputUtils.mouseX(), InputUtils.mouseY())); + } + if(element.isToggled() && element.isClicked()) { + color = OneConfigGui.INSTANCE.closeColorSelector(); + alpha = color.getAlpha() / 255f; + String buf = Integer.toHexString(color.getRGB()); + hex = "#"+buf.substring(buf.length()-6); + } + + } + + // thanks stack overflow + public static Color HexToColor(String hex) throws NumberFormatException { + hex = hex.replace("#", ""); + switch (hex.length()) { + case 6: + return new Color( + Integer.valueOf(hex.substring(0, 2), 16), + Integer.valueOf(hex.substring(2, 4), 16), + Integer.valueOf(hex.substring(4, 6), 16)); + case 8: + return new Color( + Integer.valueOf(hex.substring(0, 2), 16), + Integer.valueOf(hex.substring(2, 4), 16), + Integer.valueOf(hex.substring(4, 6), 16), + Integer.valueOf(hex.substring(6, 8), 16)); + } + throw new NumberFormatException("Invalid hex string: " + hex); + } + + +} diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigDropdown.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigDropdown.java new file mode 100644 index 0000000..c867409 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigDropdown.java @@ -0,0 +1,167 @@ +package cc.polyfrost.oneconfig.gui.elements.config; + +import cc.polyfrost.oneconfig.config.OneConfigConfig; +import cc.polyfrost.oneconfig.config.interfaces.BasicOption; +import cc.polyfrost.oneconfig.lwjgl.RenderManager; +import cc.polyfrost.oneconfig.lwjgl.font.Fonts; +import cc.polyfrost.oneconfig.lwjgl.image.Images; +import cc.polyfrost.oneconfig.utils.ColorUtils; +import cc.polyfrost.oneconfig.utils.InputUtils; +import org.lwjgl.input.Mouse; +import org.lwjgl.nanovg.NanoVG; + +import java.awt.*; +import java.lang.reflect.Field; +import java.util.Arrays; + +public class ConfigDropdown extends BasicOption { // TODO: chose where dividers are somehow idfk please send help + private final String[] options; + private int backgroundColor = OneConfigConfig.GRAY_500; + private boolean opened = false; + private int[] dividers; + + public ConfigDropdown(Field field, String name, int size, String[] options, int [] dividers) { + super(field, name, size); + this.options = options; + this.dividers = dividers; + } + + @Override + public void draw(long vg, int x, int y) { + RenderManager.drawString(vg, name, x, y + 16, OneConfigConfig.WHITE_90, 14f, Fonts.INTER_MEDIUM); + + boolean hovered; + if (size == 1) hovered = InputUtils.isAreaHovered(x + 224, y, 256, 32); + else hovered = InputUtils.isAreaHovered(x + 352, y, 640, 32); + + if (hovered && InputUtils.isClicked() || opened && InputUtils.isClicked() && + (size == 1 && !InputUtils.isAreaHovered(x + 224, y + 40, 256, options.length * 32 + 4) || + size == 2 && !InputUtils.isAreaHovered(x + 352, y + 40, 640, options.length * 32 + 4))) + opened = !opened; + if (opened) return; + + backgroundColor = ColorUtils.smoothColor(backgroundColor, OneConfigConfig.GRAY_500, OneConfigConfig.GRAY_400, hovered, 100); + int selected = 0; + try { + selected = (int) get(); + } catch (IllegalAccessException ignored) { + } + + if (hovered && Mouse.isButtonDown(0)) NanoVG.nvgGlobalAlpha(vg, 0.8f); + if (size == 1) { + RenderManager.drawRoundedRect(vg, x + 224, y, 256, 32, backgroundColor, 12); + RenderManager.drawString(vg, options[selected], x + 236, y + 16, OneConfigConfig.WHITE_80, 14f, Fonts.INTER_MEDIUM); + RenderManager.drawRoundedRect(vg, x + 452, y + 4, 24, 24, OneConfigConfig.BLUE_600, 8); + RenderManager.drawImage(vg, Images.DROPDOWN_ARROW, x + 459, y + 8, 10, 6); + NanoVG.nvgTranslate(vg, x + 469, y + 24); + } else { + RenderManager.drawRoundedRect(vg, x + 352, y, 640, 32, backgroundColor, 12); + RenderManager.drawString(vg, options[selected], x + 364, y + 16, OneConfigConfig.WHITE_80, 14f, Fonts.INTER_MEDIUM); + RenderManager.drawRoundedRect(vg, x + 964, y + 4, 24, 24, OneConfigConfig.BLUE_600, 8); + RenderManager.drawImage(vg, Images.DROPDOWN_ARROW, x + 971, y + 8, 10, 6); + NanoVG.nvgTranslate(vg, x + 981, y + 24); + } + NanoVG.nvgRotate(vg, (float) Math.toRadians(180)); + RenderManager.drawImage(vg, Images.DROPDOWN_ARROW, 0, 0, 10, 6); + NanoVG.nvgResetTransform(vg); + NanoVG.nvgGlobalAlpha(vg, 1f); + } + + @Override + public void drawLast(long vg, int x, int y) { + if (!opened) return; + + boolean hovered; + if (size == 1) hovered = InputUtils.isAreaHovered(x + 224, y, 256, 32); + else hovered = InputUtils.isAreaHovered(x + 352, y, 640, 32); + + backgroundColor = ColorUtils.smoothColor(backgroundColor, OneConfigConfig.BLUE_800, OneConfigConfig.BLUE_700, hovered, 100); + int selected = 0; + try { + selected = (int) get(); + } catch (IllegalAccessException ignored) { + } + + if (hovered && Mouse.isButtonDown(0)) NanoVG.nvgGlobalAlpha(vg, 0.8f); + if (size == 1) { + RenderManager.drawRoundedRect(vg, x + 224, y, 256, 32, backgroundColor, 12); + RenderManager.drawString(vg, options[selected], x + 236, y + 16, OneConfigConfig.WHITE_80, 14f, Fonts.INTER_MEDIUM); + + NanoVG.nvgGlobalAlpha(vg, 1f); + RenderManager.drawRoundedRect(vg, x + 224, y + 40, 256, options.length * 32 + 4, OneConfigConfig.GRAY_700, 12); + RenderManager.drawHollowRoundRect(vg, x + 224, y + 40, 256, options.length * 32 + 4, new Color(204, 204, 204, 77).getRGB(), 8, 1); + int optionY = y + 56; + for (String option : options) { + int color = OneConfigConfig.WHITE_80; + boolean optionHovered = InputUtils.isAreaHovered(x + 224, optionY - 16, 252, 32); + if (optionHovered && Mouse.isButtonDown(0)) { + RenderManager.drawRoundedRect(vg, x + 228, optionY - 12, 248, 28, OneConfigConfig.BLUE_700_80, 8); + } else if (optionHovered) { + RenderManager.drawRoundedRect(vg, x + 228, optionY - 12, 248, 28, OneConfigConfig.BLUE_700, 8); + color = OneConfigConfig.WHITE; + } + if (optionHovered && InputUtils.isClicked()) { + try { + set(Arrays.asList(options).indexOf(option)); + } catch (IllegalAccessException ignored) { + } + opened = false; + } + + RenderManager.drawString(vg, option, x + 240, optionY + 4, color, 14, Fonts.INTER_MEDIUM); + if (!options[options.length - 1].equals(option)) + RenderManager.drawLine(vg, x + 232, optionY + 18, x + 472, optionY + 18, 1, new Color(204, 204, 204, 77).getRGB()); + optionY += 32; + } + + if (hovered && Mouse.isButtonDown(0)) NanoVG.nvgGlobalAlpha(vg, 0.8f); + RenderManager.drawRoundedRect(vg, x + 452, y + 4, 24, 24, OneConfigConfig.BLUE_600, 8); + RenderManager.drawImage(vg, Images.DROPDOWN_ARROW, x + 459, y + 8, 10, 6); + NanoVG.nvgTranslate(vg, x + 469, y + 24); + } else { + RenderManager.drawRoundedRect(vg, x + 352, y, 640, 32, backgroundColor, 12); + RenderManager.drawString(vg, options[selected], x + 364, y + 16, OneConfigConfig.WHITE_80, 14f, Fonts.INTER_MEDIUM); + + RenderManager.drawRoundedRect(vg, x + 352, y + 40, 640, options.length * 32 + 4, OneConfigConfig.GRAY_700, 12); + RenderManager.drawHollowRoundRect(vg, x + 352, y + 40, 640, options.length * 32 + 4, new Color(204, 204, 204, 77).getRGB(), 8, 1); + int optionY = y + 56; + for (String option : options) { + int color = OneConfigConfig.WHITE_80; + boolean optionHovered = InputUtils.isAreaHovered(x + 352, optionY - 16, 640, 32); + if (optionHovered && Mouse.isButtonDown(0)) { + RenderManager.drawRoundedRect(vg, x + 356, optionY - 12, 632, 28, OneConfigConfig.BLUE_700_80, 8); + } else if (optionHovered) { + RenderManager.drawRoundedRect(vg, x + 356, optionY - 12, 632, 28, OneConfigConfig.BLUE_700, 8); + color = OneConfigConfig.WHITE; + } + + RenderManager.drawString(vg, option, x + 368, optionY + 4, color, 14, Fonts.INTER_MEDIUM); + if (!options[options.length - 1].equals(option)) + RenderManager.drawLine(vg, x + 360, optionY + 18, x + 984, optionY + 18, 1, new Color(204, 204, 204, 77).getRGB()); + + if (optionHovered && InputUtils.isClicked()) { + try { + set(Arrays.asList(options).indexOf(option)); + } catch (IllegalAccessException ignored) { + } + opened = false; + } + optionY += 32; + } + + if (hovered && Mouse.isButtonDown(0)) NanoVG.nvgGlobalAlpha(vg, 0.8f); + RenderManager.drawRoundedRect(vg, x + 964, y + 4, 24, 24, OneConfigConfig.BLUE_600, 8); + RenderManager.drawImage(vg, Images.DROPDOWN_ARROW, x + 971, y + 8, 10, 6); + NanoVG.nvgTranslate(vg, x + 981, y + 24); + } + NanoVG.nvgRotate(vg, (float) Math.toRadians(180)); + RenderManager.drawImage(vg, Images.DROPDOWN_ARROW, 0, 0, 10, 6); + NanoVG.nvgResetTransform(vg); + NanoVG.nvgGlobalAlpha(vg, 1f); + } + + @Override + public int getHeight() { + return 32; + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigDualOption.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigDualOption.java new file mode 100644 index 0000000..ed908b6 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigDualOption.java @@ -0,0 +1,53 @@ +package cc.polyfrost.oneconfig.gui.elements.config; + +import cc.polyfrost.oneconfig.config.OneConfigConfig; +import cc.polyfrost.oneconfig.config.interfaces.BasicOption; +import cc.polyfrost.oneconfig.lwjgl.RenderManager; +import cc.polyfrost.oneconfig.lwjgl.font.Fonts; +import cc.polyfrost.oneconfig.utils.InputUtils; +import cc.polyfrost.oneconfig.utils.MathUtils; + +import java.lang.reflect.Field; + +public class ConfigDualOption extends BasicOption { + private float percentMove = 0f; + private final String left, right; + + public ConfigDualOption(Field field, String name, int size, String[] options) { + super(field, name, size); + this.left = options[0]; + this.right = options[1]; + + } + + @Override + public int getHeight() { + return 32; + } + + @Override + public void draw(long vg, int x, int y) { + boolean toggled = false; + try { + toggled = (boolean) get(); + } catch (IllegalAccessException ignored) { + } + RenderManager.drawString(vg, name, x, y + 16, OneConfigConfig.WHITE_90, 14f, Fonts.INTER_MEDIUM); + RenderManager.drawRoundedRect(vg, x + 226, y, 256, 32, OneConfigConfig.GRAY_500, 12f); + int x1 = (int) (x + 228 + (percentMove * 128)); + RenderManager.drawRoundedRect(vg, x1, y + 2, 124, 28, OneConfigConfig.BLUE_600, 10f); + RenderManager.drawString(vg, left, x + 290 - RenderManager.getTextWidth(vg, left, 12f, Fonts.INTER_MEDIUM) / 2, y + 17, OneConfigConfig.WHITE_90, 12f, Fonts.INTER_MEDIUM); + RenderManager.drawString(vg, right, x + 418 - RenderManager.getTextWidth(vg, right, 12f, Fonts.INTER_MEDIUM) / 2, y + 17, OneConfigConfig.WHITE_90, 12f, Fonts.INTER_MEDIUM); + + if (InputUtils.isAreaClicked(x + 226, y, 256, 32)) { + toggled = !toggled; + try { + set(toggled); + } catch (IllegalAccessException e) { + System.err.println("failed to write config value: class=" + this + " fieldWatching=" + field + " valueWrite=" + toggled); + e.printStackTrace(); + } + } + percentMove = MathUtils.clamp(MathUtils.easeOut(percentMove, toggled ? 1f : 0f, 10)); + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigPageButton.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigPageButton.java new file mode 100644 index 0000000..81e1dd0 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigPageButton.java @@ -0,0 +1,57 @@ +package cc.polyfrost.oneconfig.gui.elements.config; + +import cc.polyfrost.oneconfig.config.OneConfigConfig; +import cc.polyfrost.oneconfig.config.data.OptionPage; +import cc.polyfrost.oneconfig.config.interfaces.BasicOption; +import cc.polyfrost.oneconfig.gui.OneConfigGui; +import cc.polyfrost.oneconfig.gui.pages.ModConfigPage; +import cc.polyfrost.oneconfig.lwjgl.RenderManager; +import cc.polyfrost.oneconfig.lwjgl.font.Fonts; +import cc.polyfrost.oneconfig.lwjgl.image.Images; +import cc.polyfrost.oneconfig.utils.ColorUtils; +import cc.polyfrost.oneconfig.utils.InputUtils; +import org.lwjgl.input.Mouse; +import org.lwjgl.nanovg.NanoVG; + +import java.lang.reflect.Field; + +public class ConfigPageButton extends BasicOption { + public final OptionPage page; + public final String description; + private int backgroundColor = OneConfigConfig.GRAY_500; + + public ConfigPageButton(Field field, String name, String description, OptionPage page) { + super(field, name, 2); + this.description = description; + this.page = page; + } + + @Override + public void draw(long vg, int x, int y) { + int height = description.equals("") ? 64 : 96; + boolean hovered = InputUtils.isAreaHovered(x - 2, y, 1024, height); + boolean clicked = InputUtils.isAreaClicked(x - 2, y, 1024, height); + backgroundColor = ColorUtils.smoothColor(backgroundColor, OneConfigConfig.GRAY_500, OneConfigConfig.GRAY_400, hovered, 100); + + if (hovered && Mouse.isButtonDown(0)) NanoVG.nvgGlobalAlpha(vg, 0.8f); + + RenderManager.drawRoundedRect(vg, x - 16, y, 1024, height, backgroundColor, 20); + RenderManager.drawString(vg, name, x + 10, y + 32, OneConfigConfig.WHITE_90, 24, Fonts.INTER_MEDIUM); + if (!description.equals("")) + RenderManager.drawString(vg, name, x + 10, y + 70, OneConfigConfig.WHITE_90, 14, Fonts.INTER_MEDIUM); + RenderManager.drawImage(vg, Images.CHEVRON_ARROW, x + 981f, y + (description.equals("") ? 20f : 36f), 13, 22); + + if (clicked) OneConfigGui.INSTANCE.openPage(new ModConfigPage(page)); + NanoVG.nvgGlobalAlpha(vg, 1f); + } + + @Override + public int getHeight() { + return description.equals("") ? 64 : 96; + } + + @Override + public boolean hasHalfSize() { + return false; + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigSlider.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigSlider.java new file mode 100644 index 0000000..69cb887 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigSlider.java @@ -0,0 +1,184 @@ +package cc.polyfrost.oneconfig.gui.elements.config; + +import cc.polyfrost.oneconfig.config.OneConfigConfig; +import cc.polyfrost.oneconfig.config.interfaces.BasicOption; +import cc.polyfrost.oneconfig.lwjgl.RenderManager; +import cc.polyfrost.oneconfig.lwjgl.font.Fonts; +import cc.polyfrost.oneconfig.lwjgl.image.Images; +import cc.polyfrost.oneconfig.utils.ColorUtils; +import cc.polyfrost.oneconfig.utils.InputUtils; +import cc.polyfrost.oneconfig.utils.MathUtils; +import cc.polyfrost.oneconfig.gui.elements.BasicElement; +import cc.polyfrost.oneconfig.gui.elements.TextInputField; +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 int steps = 0; + private int colorTop, colorBottom; + private boolean isFloat = true; + private Float prevAsNum = null; + private final int step; + + 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; + if (step > 0) { + steps = (int) ((max - min) / step); + } + slideYBoi.setCustomHitbox(28, 8); + inputField.onlyAcceptNumbers(true); + inputField.setCentered(true); + } + + @Override + public int getHeight() { + return 32; + } + + @Override + public void draw(long vg, int x, int y) { + float value = 0; + try { + Object object = get(); + if (object instanceof Integer) + isFloat = false; + if (isFloat) value = (float) object; + else value = (int) object; + if (prevAsNum == null) prevAsNum = value; + } catch (IllegalAccessException ignored) { + } + float current = MathUtils.clamp((value - min) / (max - min)); + + 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 (steps == 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.drawString(vg, name, x, y + 17, OneConfigConfig.WHITE_90, 14f, 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 (steps != 0) { + for (float i = 0; i <= 1.005f; i += 1f / steps) { // 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 (steps == 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 (steps == 0) { + current = MathUtils.clamp(mouseX / 512f); + } else current = MathUtils.clamp(toNearestStep(mouseX / 512f)); + } + if (slideYBoi.isHovered() && Mouse.isButtonDown(0)) { + if (steps == 0) { + current = MathUtils.clamp(mouseX / 512f); + } else current = MathUtils.clamp(toNearestStep(mouseX / 512f)); + } + currentAsNum = current * (max - min) + min; + + 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()) { + currentAsNum += step == 0 ? 1 : step; + current = MathUtils.clamp((currentAsNum - min) / (max - min)); + } + if (downArrow.isClicked()) { + currentAsNum -= step == 0 ? 1 : step; + current = MathUtils.clamp((currentAsNum - min) / (max - min)); + } + if (current == 1f) NanoVG.nvgGlobalAlpha(vg, 0.3f); + RenderManager.drawRoundedRectVaried(vg, x + 980, y, 12, 14, colorTop, 6f, 6f, 0f, 0f); + RenderManager.drawImage(vg, Images.UP_ARROW, 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, Images.UP_ARROW, 0, 0, 10, 10); + NanoVG.nvgResetTransform(vg); + NanoVG.nvgGlobalAlpha(vg, 1f); + + if (currentAsNum != prevAsNum) { + try { + if (isFloat) set(currentAsNum); + else set(Math.round(currentAsNum)); + } catch (IllegalAccessException ignored) { + } + prevAsNum = currentAsNum; + } + } + + private float toNearestStep(float input) { + float stepF = 1f / steps; + 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); + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigSwitch.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigSwitch.java new file mode 100644 index 0000000..01e2f14 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigSwitch.java @@ -0,0 +1,54 @@ +package cc.polyfrost.oneconfig.gui.elements.config; + +import cc.polyfrost.oneconfig.config.OneConfigConfig; +import cc.polyfrost.oneconfig.config.interfaces.BasicOption; +import cc.polyfrost.oneconfig.lwjgl.RenderManager; +import cc.polyfrost.oneconfig.lwjgl.font.Fonts; +import cc.polyfrost.oneconfig.utils.ColorUtils; +import cc.polyfrost.oneconfig.utils.InputUtils; +import cc.polyfrost.oneconfig.utils.MathUtils; + +import java.lang.reflect.Field; + +public class ConfigSwitch extends BasicOption { + private int color; + private float percentOn = 0f; + + public ConfigSwitch(Field field, String name, int size) { + super(field, name, size); + + } + + @Override + public void draw(long vg, int x, int y) { + boolean toggled = false; + try { + toggled = (boolean) get(); + } catch (IllegalAccessException ignored) { + } + int x2 = x + 3 + (int) (percentOn * 18); + color = ColorUtils.smoothColor(color, OneConfigConfig.GRAY_400, OneConfigConfig.BLUE_500, toggled, 20f); + if (color == -15123643) { + color = OneConfigConfig.GRAY_400; + } + RenderManager.drawRoundedRect(vg, x, y + 4, 42, 24, color, 12f); + RenderManager.drawRoundedRect(vg, x2, y + 7, 18, 18, OneConfigConfig.WHITE, 9f); + RenderManager.drawString(vg, name, x + 50, y + 17, OneConfigConfig.WHITE, 14f, Fonts.INTER_MEDIUM); + + if (InputUtils.isAreaClicked(x, y, 42, 32)) { + toggled = !toggled; + try { + set(toggled); + } catch (IllegalAccessException e) { + System.err.println("failed to write config value: class=" + this + " fieldWatching=" + field + " valueWrite=" + toggled); + e.printStackTrace(); + } + } + percentOn = MathUtils.clamp(MathUtils.easeOut(percentOn, toggled ? 1f : 0f, 10)); + } + + @Override + public int getHeight() { + return 32; + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigTextBox.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigTextBox.java new file mode 100644 index 0000000..94ed127 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigTextBox.java @@ -0,0 +1,61 @@ +package cc.polyfrost.oneconfig.gui.elements.config; + +import cc.polyfrost.oneconfig.config.OneConfigConfig; +import cc.polyfrost.oneconfig.config.interfaces.BasicOption; +import cc.polyfrost.oneconfig.lwjgl.RenderManager; +import cc.polyfrost.oneconfig.lwjgl.font.Fonts; +import cc.polyfrost.oneconfig.lwjgl.image.Images; +import cc.polyfrost.oneconfig.utils.InputUtils; +import cc.polyfrost.oneconfig.gui.elements.TextInputField; + +import java.awt.*; +import java.lang.reflect.Field; + +public class ConfigTextBox extends BasicOption { + private final boolean secure; + private final boolean multiLine; + private final TextInputField textField; + + public ConfigTextBox(Field field, String name, int size, String placeholder, boolean secure, boolean multiLine) { + super(field, name, size); + this.secure = secure; + this.multiLine = multiLine; + this.textField = new TextInputField(size == 1 && hasHalfSize() ? 256 : 640, multiLine ? 64 : 32, placeholder, multiLine, secure); + } + + @Override + public void draw(long vg, int x, int y) { + RenderManager.drawString(vg, name, x, y + 16, OneConfigConfig.WHITE_90, 14, Fonts.INTER_MEDIUM); + + try { + String value = (String) get(); + textField.setInput(value == null ? "" : value); + } catch (IllegalAccessException ignored) { + } + + textField.draw(vg, x + (size == 1 && hasHalfSize() ? 224 : 352), y); + + if (secure) + RenderManager.drawImage(vg, Images.HIDE_EYE, x + 967, y + 7, 18, 18, new Color(196, 196, 196).getRGB()); + if (secure && InputUtils.isAreaClicked(x + 967, y + 7, 18, 18)) textField.setPassword(!textField.getPassword()); + } + + @Override + public void keyTyped(char key, int keyCode) { + textField.keyTyped(key, keyCode); + try { + set(textField.getInput()); + } catch (IllegalAccessException ignored) { + } + } + + @Override + public int getHeight() { + return multiLine ? 64 : 32; + } + + @Override + public boolean hasHalfSize() { + return !secure && !multiLine; + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigUniSelector.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigUniSelector.java new file mode 100644 index 0000000..0623f1e --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigUniSelector.java @@ -0,0 +1,78 @@ +package cc.polyfrost.oneconfig.gui.elements.config; + +import cc.polyfrost.oneconfig.config.OneConfigConfig; +import cc.polyfrost.oneconfig.config.interfaces.BasicOption; +import cc.polyfrost.oneconfig.lwjgl.RenderManager; +import cc.polyfrost.oneconfig.lwjgl.Scissor; +import cc.polyfrost.oneconfig.lwjgl.ScissorManager; +import cc.polyfrost.oneconfig.lwjgl.font.Fonts; +import cc.polyfrost.oneconfig.lwjgl.image.Images; +import cc.polyfrost.oneconfig.utils.InputUtils; +import cc.polyfrost.oneconfig.utils.MathUtils; +import org.lwjgl.nanovg.NanoVG; + +import java.lang.reflect.Field; + +public class ConfigUniSelector extends BasicOption { + private final String[] options; + private float percentMove = 1f; + private int previous = -1; + + public ConfigUniSelector(Field field, String name, int size, String[] options) { + super(field, name, size); + this.options = options; + } + + @Override + public int getHeight() { + return 32; + } + + @Override + public void draw(long vg, int x, int y) { + int selected = 0; + try { + selected = (int) get(); + } catch (IllegalAccessException ignored) { + } + String option = options[selected] + " " + (selected + 1) + "/" + options.length; + RenderManager.drawString(vg, name, x, y + 16, OneConfigConfig.WHITE_90, 14f, Fonts.INTER_MEDIUM); + + Scissor scissor = ScissorManager.scissor(vg, x + 256, y, 192, 32); + if (previous == -1) { + RenderManager.drawString(vg, option, x + 352 - RenderManager.getTextWidth(vg, option, 12f, Fonts.INTER_MEDIUM) / 2f, y + 15, OneConfigConfig.WHITE_90, 12f, Fonts.INTER_MEDIUM); + } else { + String prevOption = options[previous] + " " + (previous + 1) + "/" + options.length; + RenderManager.drawString(vg, selected < previous ? prevOption : option, x + 352 - RenderManager.getTextWidth(vg, selected < previous ? prevOption : option, 12f, Fonts.INTER_MEDIUM) / 2f + 192 * percentMove, y + 15, OneConfigConfig.WHITE_90, 12f, Fonts.INTER_MEDIUM); + RenderManager.drawString(vg, selected < previous ? option : prevOption, x + 352 - RenderManager.getTextWidth(vg, selected < previous ? option : prevOption, 12f, Fonts.INTER_MEDIUM) / 2f - 192 * (1 - percentMove), y + 15, OneConfigConfig.WHITE_90, 12f, Fonts.INTER_MEDIUM); + } + ScissorManager.resetScissor(vg, scissor); + + // actual coordinates: 240, 7 + NanoVG.nvgTranslate(vg, x + 248, y + 21); + NanoVG.nvgRotate(vg, (float) Math.toRadians(180)); + RenderManager.drawImage(vg, Images.CHEVRON_ARROW, 0, 0, 8, 14, OneConfigConfig.BLUE_400); + NanoVG.nvgResetTransform(vg); + RenderManager.drawImage(vg, Images.CHEVRON_ARROW, x + 456, y + 7, 8, 14, OneConfigConfig.BLUE_400); + + if (InputUtils.isAreaClicked(x + 235, y + 5, 18, 18) && selected > 0) { + previous = selected; + selected -= 1; + try { + set(selected); + } catch (IllegalAccessException ignored) { + } + percentMove = selected < previous ? 0f : 1f; + } else if (InputUtils.isAreaClicked(x + 451, y + 5, 18, 18) && selected < options.length - 1) { + previous = selected; + selected += 1; + try { + set(selected); + } catch (IllegalAccessException ignored) { + } + percentMove = selected < previous ? 0f : 1f; + } + if (previous != -1) percentMove = MathUtils.easeOut(percentMove, selected < previous ? 1f : 0f, 10); + if ((selected < previous ? 1f : 0f) == percentMove) previous = -1; + } +} -- cgit