aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/cc/polyfrost/oneconfig/gui/elements
diff options
context:
space:
mode:
authorDeDiamondPro <67508414+DeDiamondPro@users.noreply.github.com>2022-05-03 18:25:32 +0200
committerDeDiamondPro <67508414+DeDiamondPro@users.noreply.github.com>2022-05-03 18:25:32 +0200
commita0ff501947a84b268e099524a06b56a6b900dad2 (patch)
treedb27ca1b28dbc7e57b8c99f54c80732d3042e856 /src/main/java/cc/polyfrost/oneconfig/gui/elements
parentb798930b21b89b81be05a31281f768667a6dd7f3 (diff)
downloadOneConfig-a0ff501947a84b268e099524a06b56a6b900dad2.tar.gz
OneConfig-a0ff501947a84b268e099524a06b56a6b900dad2.tar.bz2
OneConfig-a0ff501947a84b268e099524a06b56a6b900dad2.zip
move to cc.polyfrost
Diffstat (limited to 'src/main/java/cc/polyfrost/oneconfig/gui/elements')
-rw-r--r--src/main/java/cc/polyfrost/oneconfig/gui/elements/BasicButton.java157
-rw-r--r--src/main/java/cc/polyfrost/oneconfig/gui/elements/BasicElement.java107
-rw-r--r--src/main/java/cc/polyfrost/oneconfig/gui/elements/ColorSelector.java250
-rw-r--r--src/main/java/cc/polyfrost/oneconfig/gui/elements/ModCard.java146
-rw-r--r--src/main/java/cc/polyfrost/oneconfig/gui/elements/SearchField.java14
-rw-r--r--src/main/java/cc/polyfrost/oneconfig/gui/elements/TextInputField.java418
-rw-r--r--src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigCheckbox.java61
-rw-r--r--src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigColorElement.java115
-rw-r--r--src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigDropdown.java167
-rw-r--r--src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigDualOption.java53
-rw-r--r--src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigPageButton.java57
-rw-r--r--src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigSlider.java184
-rw-r--r--src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigSwitch.java54
-rw-r--r--src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigTextBox.java61
-rw-r--r--src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigUniSelector.java78
15 files changed, 1922 insertions, 0 deletions
diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/BasicButton.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/BasicButton.java
new file mode 100644
index 0000000..faf0b07
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/BasicButton.java
@@ -0,0 +1,157 @@
+package cc.polyfrost.oneconfig.gui.elements;
+
+import cc.polyfrost.oneconfig.gui.OneConfigGui;
+import cc.polyfrost.oneconfig.config.OneConfigConfig;
+import cc.polyfrost.oneconfig.gui.pages.Page;
+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 org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class BasicButton extends BasicElement {
+
+ protected String text;
+ protected Images fileNameLeftIco, fileNameRightIco;
+ private final int thisAlignment;
+ private final float fontSize;
+ private final int colorPalette;
+ public int x, y;
+ public static final int ALIGNMENT_LEFT = 0;
+ public static final int ALIGNMENT_CENTER = 1;
+ private boolean toggleable;
+ private Page page;
+ private Runnable runnable;
+
+ /**
+ * Create a new basic button. Used mostly on the homepage and the sidebar. Note: The button will not be drawn until you call {@link #draw(long, int, int)}.
+ * The button's content is centered on its total length, so the text is not always in the middle.
+ *
+ * @param text Text to display on the button. Has to be there.
+ * @param fileNameLeftIco file path of the icon to display on the left. Can be null if you don't want to display an icon on the left.
+ * @param fileNameRightIco file path of the icon to display on the right. Can be null if you don't want to display an icon on the right.
+ * @param colorPalette color palette to use. see {@link ColorUtils} for more info. Can support color palette of -2, which is larger font and icons. Also supports -3, which is just the text changing color.
+ * @param alignment alignment of the button. ALIGNMENT_LEFT or ALIGNMENT_CENTER.
+ */
+ public BasicButton(int width, int height, @NotNull String text, @Nullable Images fileNameLeftIco, @Nullable Images fileNameRightIco, int colorPalette, int alignment) {
+ super(width, height, colorPalette, true);
+ this.text = text;
+ if (fileNameLeftIco != null) this.fileNameLeftIco = fileNameLeftIco;
+ if (fileNameRightIco != null) this.fileNameRightIco = fileNameRightIco;
+ this.thisAlignment = alignment;
+ if (colorPalette == -2) {
+ fontSize = 24f;
+ this.colorPalette = -1;
+ } else {
+ fontSize = 14f;
+ this.colorPalette = colorPalette;
+ }
+ }
+
+ public BasicButton(int width, int height, @NotNull String text, @Nullable Images fileNameLeftIco, @Nullable Images fileNameRightIco, int colorPalette, int alignment, Page page) {
+ this(width, height, text, fileNameLeftIco, fileNameRightIco, colorPalette, alignment);
+ this.page = page;
+ }
+
+ public BasicButton(int width, int height, @NotNull String text, @Nullable Images fileNameLeftIco, @Nullable Images fileNameRightIco, int colorPalette, int alignment, boolean toggleable) {
+ this(width, height, text, fileNameLeftIco, fileNameRightIco, colorPalette, alignment);
+ this.toggleable = toggleable;
+ }
+
+ public BasicButton(int width, int height, @NotNull String text, @Nullable Images fileNameLeftIco, @Nullable Images fileNameRightIco, int colorPalette, int alignment, Runnable runnable) {
+ this(width, height, text, fileNameLeftIco, fileNameRightIco, colorPalette, alignment);
+ this.runnable = runnable;
+ }
+
+ public BasicButton(int width, int height, @NotNull String text, @Nullable Images fileNameLeftIco, @Nullable Images fileNameRightIco, int colorPalette, int alignment, boolean toggleable, Runnable runnable) {
+ this(width, height, text, fileNameLeftIco, fileNameRightIco, colorPalette, alignment, runnable);
+ this.toggleable = toggleable;
+ }
+
+ @Override
+ public void draw(long vg, int x, int y) {
+ this.x = x;
+ this.y = y;
+ int textColor = -1;
+ RenderManager.drawRectangle(vg, x, y, this.width, this.height, this.currentColor);
+ float contentWidth = RenderManager.getTextWidth(vg, text, fontSize, Fonts.INTER_MEDIUM);
+ if (fileNameLeftIco != null) {
+ contentWidth += 28;
+ }
+ if (fileNameRightIco != null) {
+ contentWidth += 28;
+ }
+
+ if (this.colorPalette == -3) {
+ textColor = OneConfigConfig.WHITE_80;
+ if (hovered) textColor = OneConfigConfig.WHITE;
+ if (clicked) textColor = OneConfigConfig.WHITE_80;
+ if (page == null) textColor = OneConfigConfig.WHITE_50;
+ }
+
+ if (thisAlignment == ALIGNMENT_CENTER) {
+ int middle = x + this.width / 2;
+ RenderManager.drawString(vg, text, middle - contentWidth / 2 + (fileNameLeftIco != null ? 28 : 0), y + ((float) height / 2) + 1, textColor, fontSize, Fonts.INTER_MEDIUM);
+ if (fileNameLeftIco != null) {
+ RenderManager.drawImage(vg, fileNameLeftIco, middle - contentWidth / 2, y + 8, 20, 20);
+ }
+ if (fileNameRightIco != null) {
+ RenderManager.drawImage(vg, fileNameRightIco, middle + contentWidth / 2 - (fileNameLeftIco != null ? 20 : 24), y + 8, 20, 20);
+ }
+ }
+ if (thisAlignment == ALIGNMENT_LEFT) {
+ if (fileNameLeftIco != null) {
+ RenderManager.drawImage(vg, fileNameLeftIco, x + 12, y + 8, 20, 20, textColor);
+ RenderManager.drawString(vg, text, x + 40, y + ((float) height / 2) + 1, textColor, fontSize, Fonts.INTER_MEDIUM);
+ } else {
+ RenderManager.drawString(vg, text, x + 12, y + ((float) height / 2) + 1, textColor, fontSize, Fonts.INTER_MEDIUM);
+ }
+ if (fileNameRightIco != null) {
+ RenderManager.drawImage(vg, fileNameRightIco, x + width - 28, y + 8, 20, 20);
+ }
+ }
+ this.update(x, y);
+ if (hoverFx) {
+ if (colorPalette == -3) {
+ currentColor = OneConfigConfig.TRANSPARENT;
+ return;
+ }
+ if (!toggleable) {
+ currentColor = ColorUtils.getColor(currentColor, colorPalette, hovered, clicked);
+ } else {
+ if (toggled) {
+ currentColor = ColorUtils.smoothColor(currentColor, OneConfigConfig.GRAY_500, OneConfigConfig.BLUE_600, true, 30f);
+ } else currentColor = ColorUtils.getColor(currentColor, colorPalette, hovered, clicked);
+ }
+ }
+ }
+
+
+ @Override
+ public void onClick() {
+ if (this.page != null) {
+ OneConfigGui.INSTANCE.openPage(page);
+ } else if (this.runnable != null) {
+ runnable.run();
+ }
+ }
+
+ @Override
+ public void update(int x, int y) {
+ if (toggleable && toggled) return;
+ super.update(x, y);
+ }
+
+ public void setToggled(boolean state) {
+ this.toggled = state;
+ }
+
+ public Page getPage() {
+ return page;
+ }
+
+ public String getText() {
+ return text;
+ }
+}
diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/BasicElement.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/BasicElement.java
new file mode 100644
index 0000000..80eec9b
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/BasicElement.java
@@ -0,0 +1,107 @@
+package cc.polyfrost.oneconfig.gui.elements;
+
+import cc.polyfrost.oneconfig.lwjgl.RenderManager;
+import cc.polyfrost.oneconfig.utils.ColorUtils;
+import cc.polyfrost.oneconfig.utils.InputUtils;
+
+public class BasicElement {
+ protected int width, height;
+ protected int colorPalette;
+ protected int hitBoxX, hitBoxY;
+ protected final boolean hoverFx;
+ protected boolean hovered = false;
+ protected boolean clicked = false;
+ protected boolean toggled = false;
+ protected boolean disabled = false;
+ protected int currentColor;
+
+ public BasicElement(int width, int height, int colorPalette, boolean hoverFx) {
+ this.height = height;
+ this.width = width;
+ this.colorPalette = colorPalette;
+ this.hoverFx = hoverFx;
+ }
+
+ public BasicElement(int width, int height, boolean hoverFx) {
+ this.height = height;
+ this.width = width;
+ this.colorPalette = -1;
+ this.hoverFx = hoverFx;
+ }
+
+
+ public void draw(long vg, int x, int y) {
+ RenderManager.drawRectangle(vg, x, y, width, height, currentColor);
+
+ update(x, y);
+ if (hoverFx) {
+ currentColor = ColorUtils.getColor(currentColor, colorPalette, hovered, clicked);
+ }
+ }
+
+ public void update(int x, int y) {
+ if(disabled) {
+ hovered = false;
+ clicked = false;
+ return;
+ }
+ hovered = InputUtils.isAreaHovered(x - hitBoxX, y - hitBoxY, width + hitBoxX, height + hitBoxY);
+ clicked = InputUtils.isClicked() && hovered;
+
+ if (hovered) {
+ if (clicked) {
+ toggled = !toggled;
+ onClick();
+ }
+ }
+ }
+
+
+ public void onClick() {
+
+ }
+
+ public void setCustomHitbox(int x, int y) {
+ hitBoxX = x;
+ hitBoxY = y;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ public void setColorPalette(int colorPalette) {
+ this.colorPalette = colorPalette;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public boolean isHovered() {
+ return hovered;
+ }
+
+ public boolean isClicked() {
+ return clicked;
+ }
+
+ public boolean isToggled() {
+ return toggled;
+ }
+
+ public boolean isDisabled() {
+ return disabled;
+ }
+ public void disable(boolean state) {
+ disabled = state;
+ }
+}
diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/ColorSelector.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/ColorSelector.java
new file mode 100644
index 0000000..83d0f7c
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/ColorSelector.java
@@ -0,0 +1,250 @@
+package cc.polyfrost.oneconfig.gui.elements;
+
+import cc.polyfrost.oneconfig.config.OneConfigConfig;
+import cc.polyfrost.oneconfig.lwjgl.RenderManager;
+import cc.polyfrost.oneconfig.utils.InputUtils;
+import org.lwjgl.input.Mouse;
+
+import java.awt.*;
+import java.util.ArrayList;
+
+public class ColorSelector {
+ private Color color;
+ private final int x, y;
+ private final int width = 416;
+ private final int height = 768;
+
+ private final BasicElement HSBButton = new BasicElement(128, 32, -1, true);
+ private final BasicElement RGBButton = new BasicElement(128, 32, -1, true);
+ private final BasicElement ChromaButton = new BasicElement(128, 32, -1, true);
+
+ private final ArrayList<BasicElement> faves = new ArrayList<>();
+ private final ArrayList<BasicElement> history = new ArrayList<>();
+ private final BasicElement closeButton = new BasicElement(32, 32, -1, true);
+
+
+ public ColorSelector(Color color, int mouseX, int mouseY) {
+ this.color = color;
+ this.y = mouseY - 768;
+ this.x = mouseX - 208;
+
+ }
+
+ public void draw(long vg) {
+ RenderManager.drawRoundedRect(vg, x, y, width, height, OneConfigConfig.GRAY_800, 20f);
+
+ }
+
+ public Color getColor() {
+ return color;
+ }
+
+
+
+ private class HSBSelector extends ColorSelectorBase {
+
+
+ public HSBSelector(Color color) {
+ super(color);
+ }
+
+ @Override
+ public void drawBox(long vg, int x, int y) {
+
+ }
+
+ @Override
+ public void setColor(Color color) {
+
+ }
+
+ @Override
+ public int[] drawTopSlider() {
+ return new int[0];
+ }
+
+ @Override
+ public int[] drawBottomSlider() {
+ return new int[0];
+ }
+
+ @Override
+ public float[] getColorAtPos(int clickX, int clickY) {
+ return new float[0];
+ }
+ }
+
+
+ private class RGBSelector extends ColorSelectorBase {
+
+ public RGBSelector(Color color) {
+ super(color);
+ }
+
+ @Override
+ public void drawBox(long vg, int x, int y) {
+
+ }
+
+ @Override
+ public void setColor(Color color) {
+
+ }
+
+ @Override
+ public int[] drawTopSlider() {
+ return new int[0];
+ }
+
+ @Override
+ public int[] drawBottomSlider() {
+ return new int[0];
+ }
+
+
+ @Override
+ public float[] getColorAtPos(int clickX, int clickY) {
+ return new float[0];
+ }
+ }
+
+
+
+ private abstract class ColorSelectorBase {
+
+ private int selectedX;
+ private int selectedY;
+ private float[] hsb = new float[3];
+ private float[] rgba;
+ private final TextInputFieldNumber hueField = new TextInputFieldNumber(72, 32, "", 0, 100);
+ private final TextInputFieldNumber saturationField = new TextInputFieldNumber(72, 32, "", 0, 100);
+ private final TextInputFieldNumber brightnessField = new TextInputFieldNumber(72, 32, "", 0, 100);
+ private final TextInputFieldNumber alphaField = new TextInputFieldNumber(72, 32, "", 0, 100);
+
+ private final TextInputField hexField = new TextInputField(107, 32, true, false, "");
+ private final TextInputFieldNumber redField = new TextInputFieldNumber(44, 32, "", 0, 255);
+ private final TextInputFieldNumber greenField = new TextInputFieldNumber(44, 32, "", 0, 255);
+ private final TextInputFieldNumber blueField = new TextInputFieldNumber(44, 32, "", 0, 255);
+
+ private final Slider sliderTop = new Slider(0);
+ private final Slider sliderBottom = new Slider(0);
+
+ public ColorSelectorBase(Color color) {
+ rgba = new float[]{color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f, color.getAlpha() / 255f};
+ }
+
+ public void updateElements(float[] rgba) {
+ this.rgba = rgba;
+ hsb = Color.RGBtoHSB((int) (rgba[0] * 255), (int) (rgba[1] * 255), (int) (rgba[2] * 255), hsb);
+ hueField.setInput(String.valueOf(hsb[0]));
+ saturationField.setInput(String.valueOf(hsb[1]));
+ brightnessField.setInput(String.valueOf(hsb[2]));
+ alphaField.setInput(String.valueOf(rgba[3]));
+ redField.setInput(String.valueOf(rgba[0]));
+ greenField.setInput(String.valueOf(rgba[1]));
+ blueField.setInput(String.valueOf(rgba[2]));
+ }
+ public abstract void drawBox(long vg, int x, int y);
+
+ /** draw the color selector contents, including the box, and the input fields. If it is clicked, getColorAtPos is called. updateElements is also called to update all the input fields. */
+ public void draw(long vg, int x, int y) {
+ drawBox(vg, x + 16, y + 120);
+ if(InputUtils.isAreaHovered(x + 16, y + 120, 384, 288) && Mouse.isButtonDown(0)) {
+ selectedX = InputUtils.mouseX() - x - 16;
+ selectedY = InputUtils.mouseY() - y - 120;
+ rgba = getColorAtPos(selectedX, selectedY);
+ } // TODO all of this
+ hueField.draw(vg, x + 104, y + 544);
+ saturationField.draw(vg, x + 312, y + 544);
+ brightnessField.draw(vg, x + 103, y + 584);
+ alphaField.draw(vg, x + 103, y + 584);
+ hexField.draw(vg, x + 96, y + 624);
+ redField.draw(vg, x + 228, y + 624);
+ greenField.draw(vg, x + 292, y + 664);
+ blueField.draw(vg, x + 356, y + 664);
+ sliderTop.draw(vg, x + 16, y + 424, drawTopSlider()[0], drawTopSlider()[1]);
+ sliderBottom.draw(vg, x + 16, y + 576, drawBottomSlider()[0], drawBottomSlider()[1]);
+ updateElements(rgba);
+ Color color1 = new Color(rgba[0], rgba[1], rgba[2], rgba[3]);
+ setColor(color1);
+ RenderManager.drawRoundedRect(vg, x + 16, y + 488, 384, 40, color1.getRGB(), 12f);
+ }
+
+ /** called to set the color of the color selector box based on the values of the input fields. */
+ public abstract void setColor(Color color);
+
+ /** return an array of two ints of the start color of the gradient and the end color of the gradient. */
+ public abstract int[] drawTopSlider();
+ /** return an array of two ints of the start color of the gradient and the end color of the gradient. */
+ public abstract int[] drawBottomSlider();
+
+ /**
+ * This method is called when the color selector is clicked. It needs to return color at the clicked position.
+ * @return color at the clicked position as a <code>float[] rgba.</code>
+ */
+ public abstract float[] getColorAtPos(int clickX, int clickY);
+
+ public float getRed() {
+ return rgba[0];
+ }
+ public float getGreen(){
+ return rgba[1];
+ }
+ public float getBlue(){
+ return rgba[2];
+ }
+ public float getAlpha(){
+ return rgba[3];
+ }
+
+ public float getHue(){
+ return hsb[0];
+ }
+
+ public float getSaturation(){
+ return hsb[1];
+ }
+
+ public float getBrightness(){
+ return hsb[2];
+ }
+
+ public String getHex() {
+ return null;
+ };
+
+ public Color getColor() {
+ return new Color(rgba[0], rgba[1], rgba[2], rgba[3]);
+ }
+
+ }
+
+ private class TextInputFieldNumber extends TextInputField {
+ private final float min, max;
+ public TextInputFieldNumber(int width, int height, String defaultValue, float min, float max) {
+ super(width, height, true, true, defaultValue);
+ this.min = min;
+ this.max = max;
+ }
+
+ @Override
+ public void draw(long vg, int x, int y) {
+ super.draw(vg, x, y);
+
+ }
+ }
+
+ private class Slider {
+ private final int style;
+
+ public Slider(int style) {
+ this.style = style;
+ }
+
+ public void draw(long vg, int x, int y, int color1, int color2) {
+
+ }
+ }
+}
+
+
diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/ModCard.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/ModCard.java
new file mode 100644
index 0000000..4fe1524
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/ModCard.java
@@ -0,0 +1,146 @@
+package cc.polyfrost.oneconfig.gui.elements;
+
+import cc.polyfrost.oneconfig.OneConfig;
+import cc.polyfrost.oneconfig.config.OneConfigConfig;
+import cc.polyfrost.oneconfig.config.data.Mod;
+import cc.polyfrost.oneconfig.config.data.ModType;
+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 net.minecraft.client.Minecraft;
+import net.minecraft.command.CommandException;
+import net.minecraftforge.client.ClientCommandHandler;
+import net.minecraftforge.fml.common.ModMetadata;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.lwjgl.nanovg.NanoVG;
+
+import java.util.ArrayList;
+
+public class ModCard extends BasicElement {
+ private final String iconPath;
+ private final Mod modData;
+ private final BasicElement favoriteHitbox = new BasicElement(32, 32, -2, true);
+ private boolean active, disabled, favorite;
+ private int colorGray = OneConfigConfig.GRAY_600;
+ private int colorPrimary = OneConfigConfig.BLUE_600;
+ private boolean isHoveredMain = false;
+
+ public ModCard(@NotNull Mod mod, @Nullable String iconPath, boolean active, boolean disabled, boolean favorite) {
+ super(244, 119, false);
+ this.modData = mod;
+ this.iconPath = iconPath;
+ this.active = active;
+ toggled = active;
+ this.disabled = disabled;
+ this.favorite = favorite;
+ }
+
+ @Override
+ public void draw(long vg, int x, int y) {
+ if (disabled) NanoVG.nvgGlobalAlpha(vg, 0.5f);
+ RenderManager.drawRoundedRectVaried(vg, x, y, width, 87, colorGray, 12f, 12f, 0f, 0f);
+ RenderManager.drawRoundedRectVaried(vg, x, y + 87, width, 32, colorPrimary, 0f, 0f, 12f, 12f);
+ RenderManager.drawLine(vg, x, y + 86, x + width, y + 86, 2, OneConfigConfig.GRAY_300);
+ if (iconPath != null) {
+ RenderManager.drawImage(vg, iconPath, x, y, width, 87);
+ } else {
+ RenderManager.drawImage(vg, Images.MOD_BOX, x + 98, y + 19, 48, 48);
+ }
+ favoriteHitbox.update(x + 212, y + 87);
+ favoriteHitbox.currentColor = ColorUtils.getColor(favoriteHitbox.currentColor, favoriteHitbox.colorPalette, favoriteHitbox.hovered, favoriteHitbox.clicked);
+ RenderManager.drawRoundedRectVaried(vg, x + 212, y + 87, 32, 32, favoriteHitbox.currentColor, 0f, 0f, 12f, 0f);
+ favorite = favoriteHitbox.isToggled();
+ RenderManager.drawString(vg, modData.name, x + 12, y + 103, OneConfigConfig.WHITE, 14f, Fonts.INTER_MEDIUM);
+ if (favorite) {
+ RenderManager.drawImage(vg, Images.FAVORITE, x + 220, y + 95, 16, 16);
+ } else {
+ RenderManager.drawImage(vg, Images.FAVORITE_OFF, x + 220, y + 95, 16, 16);
+ }
+ super.update(x, y);
+ isHoveredMain = InputUtils.isAreaHovered(x, y, width, 87);
+ boolean isHoveredSecondary = InputUtils.isAreaHovered(x, y + 87, width - 32, 32) && !disabled;
+ colorGray = ColorUtils.getColor(colorGray, 0, isHoveredMain, clicked && isHoveredMain);
+ if (active && !disabled) {
+ colorPrimary = ColorUtils.getColor(colorPrimary, 1, isHoveredSecondary, clicked && isHoveredSecondary);
+ } else
+ colorPrimary = ColorUtils.smoothColor(colorPrimary, OneConfigConfig.GRAY_500, OneConfigConfig.GRAY_400, isHoveredSecondary, 20f);
+
+ if (clicked && isHoveredMain) {
+ if (!active) toggled = false;
+ }
+ if (clicked && favoriteHitbox.hovered) toggled = false;
+ if (clicked && !isHoveredSecondary && active) toggled = true;
+ if (!active & disabled) toggled = false;
+ //RenderManager.drawString(vg, "active=" + active, x + 150, y + 92, OneConfigConfig.WHITE, 10f, Fonts.INTER_MEDIUM); // debug stuff
+ //RenderManager.drawString(vg, "disabled=" + disabled, x + 150, y + 103, OneConfigConfig.WHITE, 10f, Fonts.INTER_MEDIUM);
+ //RenderManager.drawString(vg, "favorite=" + favorite, x + 150, y + 114, OneConfigConfig.WHITE, 10f, Fonts.INTER_MEDIUM);
+
+
+ active = toggled;
+ NanoVG.nvgGlobalAlpha(vg, 1f);
+ }
+
+ public void onClick() {
+ if (isHoveredMain) {
+ for (Mod data : OneConfig.loadedMods) {
+ if (data.modType != ModType.OTHER) {
+ if (data.name.equalsIgnoreCase(modData.name)) {
+ OneConfigGui.INSTANCE.openPage(new ModConfigPage(data.defaultPage));
+ }
+ }
+ }
+ for (ModMetadata mod : OneConfig.loadedOtherMods) {
+ if (mod.name.equalsIgnoreCase(modData.name)) {
+ ArrayList<String> possibleCommands = new ArrayList<>();
+ possibleCommands.add(mod.name.toLowerCase().replace(" ", ""));
+ possibleCommands.add(mod.modId.toLowerCase().replaceAll("[ -_]", ""));
+ if (mod.name.split(" ").length > 1) {
+ StringBuilder result = new StringBuilder();
+ for (String word : mod.name.split(" ")) {
+ if (word.length() == 0) continue;
+ result.append(word.charAt(0));
+ }
+ possibleCommands.add(result.toString().toLowerCase());
+ }
+ for (String command : ClientCommandHandler.instance.getCommands().keySet()) {
+ if (possibleCommands.contains(command)) {
+ try {
+ ClientCommandHandler.instance.getCommands().get(command).processCommand(Minecraft.getMinecraft().thePlayer, new String[]{});
+ } catch (CommandException e) {
+ throw new RuntimeException(e);
+ }
+ break;
+ }
+ }
+ return;
+ }
+
+ }
+ }
+ }
+
+ public Mod getModData() {
+ return modData;
+ }
+
+ public boolean isDisabled() {
+ return disabled;
+ }
+
+ public boolean isActive() {
+ return active;
+ }
+
+ public void setDisabled(boolean disabled) {
+ this.disabled = disabled;
+ }
+
+ public boolean isFavorite() {
+ return favorite;
+ }
+}
diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/SearchField.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/SearchField.java
new file mode 100644
index 0000000..6f460d6
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/SearchField.java
@@ -0,0 +1,14 @@
+package cc.polyfrost.oneconfig.gui.elements;
+
+public class SearchField extends TextInputField {
+
+ public SearchField(int width, int height, String defaultText, boolean multiLine, boolean password) {
+ super(width, height, defaultText, multiLine, password);
+ }
+
+ @Override
+ public void draw(long vg, int x, int y) {
+ super.draw(vg, x, y);
+ // TODO
+ }
+}
diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/TextInputField.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/TextInputField.java
new file mode 100644
index 0000000..3058643
--- /dev/null
+++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/TextInputField.java
@@ -0,0 +1,418 @@
+package cc.polyfrost.oneconfig.gui.elements;
+
+import cc.polyfrost.oneconfig.config.OneConfigConfig;
+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.utils.InputUtils;
+import net.minecraft.client.gui.GuiScreen;
+import net.minecraft.util.ChatAllowedCharacters;
+import org.jetbrains.annotations.NotNull;
+import org.lwjgl.input.Keyboard;
+import org.lwjgl.input.Mouse;
+
+import java.awt.*;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.StringSelection;
+
+public class TextInputField extends BasicElement {
+
+ protected final String defaultText;
+ protected String input, selectedText;
+ protected final boolean multiLine;
+ protected boolean password;
+
+ protected int caretPos;
+ protected int x, y;
+ protected float start, end;
+ private long clickTimeD1;
+ 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);
+ this.multiLine = multiLine;
+ this.defaultText = defaultText;
+ this.password = password;
+ this.input = "";
+ }
+
+ public TextInputField(int width, int height, boolean centered, boolean onlyNums, String defaultText) {
+ this(width, height, defaultText, false, false);
+ this.centered = centered;
+ this.onlyNums = onlyNums;
+ }
+
+ public void onlyAcceptNumbers(boolean state) {
+ onlyNums = state;
+ }
+
+ public void setInput(String input) {
+ this.input = input;
+ }
+
+ public String getInput() {
+ return input;
+ }
+
+ public void setPassword(boolean password) {
+ this.password = password;
+ }
+
+ public boolean getPassword() {
+ 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 {
+ Scissor scissor = ScissorManager.scissor(vg, x, y, width, height);
+ 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) {
+ width = RenderManager.getTextWidth(vg, input.substring(0, caretPos), 14f, Fonts.INTER_REGULAR);
+ } else {
+ for (int i = 0; i < input.length(); i++) {
+ s.append("*");
+ }
+ width = RenderManager.getTextWidth(vg, s.substring(0, caretPos), 14f, Fonts.INTER_REGULAR);
+ }
+ if (hovered) {
+ while (Mouse.next()) {
+ if (Mouse.getEventButtonState()) {
+ if (Mouse.getEventButton() == 0) {
+ prevCaret = calculatePos(Mouse.getX());
+ if (System.currentTimeMillis() - clickTimeD1 < 300) {
+