From 0efc327a74c128fd9b694872643f0fd090ca1363 Mon Sep 17 00:00:00 2001
From: DeDiamondPro <67508414+DeDiamondPro@users.noreply.github.com>
Date: Sun, 1 May 2022 16:40:36 +0200
Subject: dropdown

---
 .../oneconfig/config/OneConfigConfig.java          |   2 +
 .../gui/elements/config/ConfigDropdown.java        | 116 ++++++++++++++++++++-
 .../gui/elements/config/ConfigPageButton.java      |   3 +-
 .../gui/elements/config/ConfigSlider.java          |  95 ++++++++---------
 .../io/polyfrost/oneconfig/test/TestConfig.java    |   4 +-
 5 files changed, 159 insertions(+), 61 deletions(-)

(limited to 'src/main')

diff --git a/src/main/java/io/polyfrost/oneconfig/config/OneConfigConfig.java b/src/main/java/io/polyfrost/oneconfig/config/OneConfigConfig.java
index da6b4c2..30eb6ab 100644
--- a/src/main/java/io/polyfrost/oneconfig/config/OneConfigConfig.java
+++ b/src/main/java/io/polyfrost/oneconfig/config/OneConfigConfig.java
@@ -29,7 +29,9 @@ public class OneConfigConfig extends Config {
     public static final int GRAY_300 = new Color(73, 79, 92, 255).getRGB();           // Gray 300         // button gray hover
     public static final int GRAY_200 = new Color(100, 107, 125, 255).getRGB();        // Gray 200
     public static final int GRAY_400_80 = new Color(55, 59, 69, 204).getRGB();        // Gray 400 80%     // button gray pressed
+    public static final int BLUE_800 = new Color(13, 51, 128, 255).getRGB();          // Blue 800
     public static final int BLUE_700 = new Color(18, 71, 178, 255).getRGB();          // Blue 700
+    public static final int BLUE_700_80 = new Color(18, 71, 178, 204).getRGB();       // Blue 700 80%
     public static final int BLUE_600 = new Color(20, 82, 204, 255).getRGB();          // Blue 600         // button blue normal
     public static final int BLUE_600_80 = new Color(20, 82, 204, 204).getRGB();       // Blue 600 80%     // button blue click
     public static final int BLUE_500 = new Color(25, 103, 255, 255).getRGB();         // Blue 500         // button blue hover
diff --git a/src/main/java/io/polyfrost/oneconfig/gui/elements/config/ConfigDropdown.java b/src/main/java/io/polyfrost/oneconfig/gui/elements/config/ConfigDropdown.java
index 3e21dfe..921ad10 100644
--- a/src/main/java/io/polyfrost/oneconfig/gui/elements/config/ConfigDropdown.java
+++ b/src/main/java/io/polyfrost/oneconfig/gui/elements/config/ConfigDropdown.java
@@ -1,16 +1,24 @@
 package io.polyfrost.oneconfig.gui.elements.config;
 
+import io.polyfrost.oneconfig.OneConfig;
 import io.polyfrost.oneconfig.config.OneConfigConfig;
 import io.polyfrost.oneconfig.config.interfaces.BasicOption;
 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 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 {
     private final String[] options;
+    private int backgroundColor = OneConfigConfig.GRAY_500;
+    private boolean opened = false;
+
     public ConfigDropdown(Field field, String name, int size, String[] options) {
         super(field, name, size);
         this.options = options;
@@ -18,29 +26,128 @@ public class ConfigDropdown extends BasicOption {
 
     @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, "/assets/oneconfig/textures/dropdown_arrow.png", 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, "/assets/oneconfig/textures/dropdown_arrow.png", x + 971, y + 8, 10, 6);
+            NanoVG.nvgTranslate(vg, x + 981, y + 24);
+        }
+        NanoVG.nvgRotate(vg, (float) Math.toRadians(180));
+        RenderManager.drawImage(vg, "/assets/oneconfig/textures/dropdown_arrow.png", 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) {
         }
 
-        RenderManager.drawString(vg, name, x, y + 16, OneConfigConfig.WHITE_90, 14f, Fonts.INTER_MEDIUM);
-
+        if (hovered && Mouse.isButtonDown(0)) NanoVG.nvgGlobalAlpha(vg, 0.8f);
         if (size == 1) {
-            RenderManager.drawRoundedRect(vg, x + 224, y, 256, 32, OneConfigConfig.GRAY_500, 12);
+            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, "/assets/oneconfig/textures/dropdown_arrow.png", x + 459, y + 8, 10, 6);
             NanoVG.nvgTranslate(vg, x + 469, y + 24);
         } else {
-            RenderManager.drawRoundedRect(vg, x + 352, y, 640, 32, OneConfigConfig.GRAY_500, 12);
+            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, "/assets/oneconfig/textures/dropdown_arrow.png", x + 971, y + 8, 10, 6);
             NanoVG.nvgTranslate(vg, x + 981, y + 24);
@@ -48,6 +155,7 @@ public class ConfigDropdown extends BasicOption {
         NanoVG.nvgRotate(vg, (float) Math.toRadians(180));
         RenderManager.drawImage(vg, "/assets/oneconfig/textures/dropdown_arrow.png", 0, 0, 10, 6);
         NanoVG.nvgResetTransform(vg);
+        NanoVG.nvgGlobalAlpha(vg, 1f);
     }
 
     @Override
diff --git a/src/main/java/io/polyfrost/oneconfig/gui/elements/config/ConfigPageButton.java b/src/main/java/io/polyfrost/oneconfig/gui/elements/config/ConfigPageButton.java
index 607c877..c32b76e 100644
--- a/src/main/java/io/polyfrost/oneconfig/gui/elements/config/ConfigPageButton.java
+++ b/src/main/java/io/polyfrost/oneconfig/gui/elements/config/ConfigPageButton.java
@@ -9,6 +9,7 @@ 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 org.lwjgl.input.Mouse;
 import org.lwjgl.nanovg.NanoVG;
 
 import java.lang.reflect.Field;
@@ -31,7 +32,7 @@ public class ConfigPageButton extends BasicOption {
         boolean clicked = InputUtils.isAreaClicked(x - 2, y, 1024, height);
         backgroundColor = ColorUtils.smoothColor(backgroundColor, OneConfigConfig.GRAY_500, OneConfigConfig.GRAY_400, hovered, 100);
 
-        if (clicked) NanoVG.nvgGlobalAlpha(vg, 0.8f);
+        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);
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
index 49d31a4..25b3eab 100644
--- a/src/main/java/io/polyfrost/oneconfig/gui/elements/config/ConfigSlider.java
+++ b/src/main/java/io/polyfrost/oneconfig/gui/elements/config/ConfigSlider.java
@@ -20,17 +20,20 @@ public class ConfigSlider extends BasicOption {
     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 int steps = 0;
     private int colorTop, colorBottom;
     private boolean isFloat = true;
     private Float prevAsNum = null;
+    private 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;
-        if (step > 0) this.step = step - 1;       // it adds one more step than actual
-        else this.step = 0;
+        this.step = step;
+        if (step > 0) {
+            steps = (int) ((max - min) / step);
+        }
         slideYBoi.setCustomHitbox(28, 8);
         inputField.onlyAcceptNumbers(true);
         inputField.setCentered(true);
@@ -54,34 +57,8 @@ public class ConfigSlider extends BasicOption {
         } catch (IllegalAccessException ignored) {
         }
         float current = MathUtils.clamp((value - min) / (max - min));
-        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()) {
@@ -95,7 +72,7 @@ public class ConfigSlider extends BasicOption {
                     inputField.setErrored(true);
                     input = max;
                 }
-                if (step == 0) {
+                if (steps == 0) {
                     current = MathUtils.clamp((input - min) / (max - min));
                 } else {
                     current = toNearestStep(MathUtils.clamp((input - min) / (max - min)));
@@ -106,6 +83,34 @@ public class ConfigSlider extends BasicOption {
         }
         inputField.draw(vg, x + 892, 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 (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);
@@ -114,30 +119,12 @@ public class ConfigSlider extends BasicOption {
         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;
-                    }
-                }
-            }
+            currentAsNum += step == 0 ? 1 : step;
+            current = MathUtils.clamp((currentAsNum - min) / (max - min));
         }
         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;
-                    }
-                }
-            }
+            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);
@@ -155,7 +142,7 @@ public class ConfigSlider extends BasicOption {
         if (currentAsNum != prevAsNum) {
             try {
                 if (isFloat) set(currentAsNum);
-                else set((int) currentAsNum);
+                else set(Math.round(currentAsNum));
             } catch (IllegalAccessException ignored) {
             }
             prevAsNum = currentAsNum;
@@ -163,7 +150,7 @@ public class ConfigSlider extends BasicOption {
     }
 
     private float toNearestStep(float input) {
-        float stepF = 1f / step;
+        float stepF = 1f / steps;
         float stepAbove = 1f, stepBelow = 0f;
         for (float a = 0f; a <= 1f; a += stepF) {
             if (a > input) {
diff --git a/src/main/java/io/polyfrost/oneconfig/test/TestConfig.java b/src/main/java/io/polyfrost/oneconfig/test/TestConfig.java
index 0cb3308..c0fda13 100644
--- a/src/main/java/io/polyfrost/oneconfig/test/TestConfig.java
+++ b/src/main/java/io/polyfrost/oneconfig/test/TestConfig.java
@@ -107,7 +107,7 @@ public class TestConfig extends Config {
             min = 0,
             max = 25
     )
-    public static float slider1;
+    public static int slider1;
     @Option(
             name = "Stepped Slider",
             subcategory = "Sliders",
@@ -118,7 +118,7 @@ public class TestConfig extends Config {
             max = 30,
             step = 2
     )
-    public static int slider2;
+    public static float slider2;
 
 
     public TestConfig() {
-- 
cgit