diff options
6 files changed, 161 insertions, 82 deletions
diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/OneConfigGui.java b/src/main/java/cc/polyfrost/oneconfig/gui/OneConfigGui.java index 22b5455..66bc2cd 100644 --- a/src/main/java/cc/polyfrost/oneconfig/gui/OneConfigGui.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/OneConfigGui.java @@ -28,7 +28,7 @@ public class OneConfigGui extends UScreen { protected Page currentPage; protected Page prevPage; private float pageProgress = -224f; - private final TextInputField textInputField = new TextInputField(248, 40, "Search...", false, false); + private final TextInputField textInputField = new TextInputField(248, 40, "Search...", false, false, SVGs.SEARCH); private final ArrayList<Page> previousPages = new ArrayList<>(); private final ArrayList<Page> nextPages = new ArrayList<>(); private final BasicElement backArrow = new BasicElement(40, 40, -1, false); 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 index c01228d..f6041c9 100644 --- a/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigDropdown.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigDropdown.java @@ -35,8 +35,8 @@ public class ConfigDropdown extends BasicOption { // TODO: remove dividers and f else hovered = InputUtils.isAreaHovered(x + 352, y, 640, 32) && isEnabled(); if (hovered && InputUtils.isClicked() || opened && InputUtils.isClicked(true) && - (size == 1 && !InputUtils.isAreaHovered(x + 224, y + 40, 256, options.length * 36) || - size == 2 && !InputUtils.isAreaHovered(x + 352, y + 40, 640, options.length * 36))) { + (size == 1 && !InputUtils.isAreaHovered(x + 224, y + 40, 256, options.length * 32) || + size == 2 && !InputUtils.isAreaHovered(x + 352, y + 40, 640, options.length * 32))) { opened = !opened; InputUtils.blockClicks(opened); } @@ -88,16 +88,16 @@ public class ConfigDropdown extends BasicOption { // TODO: remove dividers and f RenderManager.drawSvg(vg, SVGs.DROPDOWN_LIST, x + 452, y + 4, 24, 24); NanoVG.nvgGlobalAlpha(vg, 1f); - RenderManager.drawRoundedRect(vg, x + 224, y + 48, 256, options.length * 36, OneConfigConfig.GRAY_700, 12); - RenderManager.drawHollowRoundRect(vg, x + 223, y + 47, 258, options.length * 36 + 2, new Color(204, 204, 204, 77).getRGB(), 11, 1); - int optionY = y + 48; + RenderManager.drawRoundedRect(vg, x + 224, y + 48, 256, options.length * 32 + 8, OneConfigConfig.GRAY_700, 12); + RenderManager.drawHollowRoundRect(vg, x + 223, y + 47, 258, options.length * 32 + 10, new Color(204, 204, 204, 77).getRGB(), 12, 1); + int optionY = y + 52; for (String option : options) { int color = OneConfigConfig.WHITE_80; - boolean optionHovered = InputUtils.isAreaHovered(x + 224, optionY, 252, 36); + boolean optionHovered = InputUtils.isAreaHovered(x + 224, optionY, 252, 32); if (optionHovered && Mouse.isButtonDown(0)) { - RenderManager.drawRoundedRect(vg, x + 228, optionY + 4, 248, 28, OneConfigConfig.BLUE_700_80, 8); + RenderManager.drawRoundedRect(vg, x + 228, optionY + 2, 248, 28, OneConfigConfig.BLUE_700_80, 8); } else if (optionHovered) { - RenderManager.drawRoundedRect(vg, x + 228, optionY + 4, 248, 28, OneConfigConfig.BLUE_700, 8); + RenderManager.drawRoundedRect(vg, x + 228, optionY + 2, 248, 28, OneConfigConfig.BLUE_700, 8); color = OneConfigConfig.WHITE; } if (optionHovered && InputUtils.isClicked(true)) { @@ -109,10 +109,8 @@ public class ConfigDropdown extends BasicOption { // TODO: remove dividers and f InputUtils.blockClicks(false); } - RenderManager.drawString(vg, option, x + 240, optionY + 20, color, 14, Fonts.MEDIUM); - if (!options[options.length - 1].equals(option)) - RenderManager.drawLine(vg, x + 232, optionY + 36, x + 472, optionY + 36, 1, new Color(204, 204, 204, 77).getRGB()); - optionY += 36; + RenderManager.drawString(vg, option, x + 240, optionY + 18, color, 14, Fonts.MEDIUM); + optionY += 32; } } else { RenderManager.drawRoundedRect(vg, x + 352, y, 640, 32, backgroundColor, 12); @@ -122,22 +120,20 @@ public class ConfigDropdown extends BasicOption { // TODO: remove dividers and f RenderManager.drawSvg(vg, SVGs.DROPDOWN_LIST, x + 964, y + 4, 24, 24); NanoVG.nvgGlobalAlpha(vg, 1f); - RenderManager.drawRoundedRect(vg, x + 352, y + 48, 640, options.length * 36, OneConfigConfig.GRAY_700, 12); - RenderManager.drawHollowRoundRect(vg, x + 351, y + 47, 642, options.length * 36 + 2, new Color(204, 204, 204, 77).getRGB(), 10, 1); - int optionY = y + 48; + RenderManager.drawRoundedRect(vg, x + 352, y + 48, 640, options.length * 32 + 8, OneConfigConfig.GRAY_700, 12); + RenderManager.drawHollowRoundRect(vg, x + 351, y + 47, 642, options.length * 32 + 10, new Color(204, 204, 204, 77).getRGB(), 12, 1); + int optionY = y + 52; for (String option : options) { int color = OneConfigConfig.WHITE_80; boolean optionHovered = InputUtils.isAreaHovered(x + 352, optionY, 640, 36); if (optionHovered && Mouse.isButtonDown(0)) { - RenderManager.drawRoundedRect(vg, x + 356, optionY + 4, 632, 28, OneConfigConfig.BLUE_700_80, 8); + RenderManager.drawRoundedRect(vg, x + 356, optionY + 2, 632, 28, OneConfigConfig.BLUE_700_80, 8); } else if (optionHovered) { - RenderManager.drawRoundedRect(vg, x + 356, optionY + 4, 632, 28, OneConfigConfig.BLUE_700, 8); + RenderManager.drawRoundedRect(vg, x + 356, optionY + 2, 632, 28, OneConfigConfig.BLUE_700, 8); color = OneConfigConfig.WHITE; } - RenderManager.drawString(vg, option, x + 368, optionY + 20, color, 14, Fonts.MEDIUM); - if (!options[options.length - 1].equals(option)) - RenderManager.drawLine(vg, x + 360, optionY + 36, x + 984, optionY + 36, 1, new Color(204, 204, 204, 77).getRGB()); + RenderManager.drawString(vg, option, x + 368, optionY + 18, color, 14, Fonts.MEDIUM); if (optionHovered && InputUtils.isClicked(true)) { try { @@ -147,7 +143,7 @@ public class ConfigDropdown extends BasicOption { // TODO: remove dividers and f opened = false; InputUtils.blockClicks(false); } - optionY += 36; + optionY += 32; } } NanoVG.nvgGlobalAlpha(vg, 1f); 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 index d420f01..dbe0482 100644 --- a/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigTextBox.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/config/ConfigTextBox.java @@ -2,12 +2,12 @@ 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.elements.text.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.lwjgl.image.SVGs; import cc.polyfrost.oneconfig.utils.InputUtils; -import cc.polyfrost.oneconfig.gui.elements.text.TextInputField; +import org.lwjgl.input.Mouse; import org.lwjgl.nanovg.NanoVG; import java.awt.*; @@ -37,11 +37,18 @@ public class ConfigTextBox extends BasicOption { } catch (IllegalAccessException ignored) { } + if (multiLine && textField.getLines() > 2) textField.setHeight(64 + 24 * (textField.getLines() - 2)); + else if (multiLine) textField.setHeight(64); textField.draw(vg, x + (size == 1 && hasHalfSize() ? 224 : 352), y); - if (secure) - RenderManager.drawSvg(vg, SVGs.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()); + if (secure) { + SVGs icon = textField.getPassword() ? SVGs.EYE_OFF : SVGs.EYE; + boolean hovered = InputUtils.isAreaHovered(x + 967, y + 7, 18, 18) && isEnabled(); + int color = hovered ? OneConfigConfig.WHITE : OneConfigConfig.WHITE_80; + if (hovered && InputUtils.isClicked()) textField.setPassword(!textField.getPassword()); + if (hovered && Mouse.isButtonDown(0)) NanoVG.nvgGlobalAlpha(vg, 0.5f); + RenderManager.drawSvg(vg, icon, x + 967, y + 7, 18, 18, color); + } NanoVG.nvgGlobalAlpha(vg, 1f); } @@ -57,7 +64,7 @@ public class ConfigTextBox extends BasicOption { @Override public int getHeight() { - return multiLine ? 64 : 32; + return multiLine ? textField.getHeight() : 32; } @Override diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/text/TextInputField.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/text/TextInputField.java index 9d87717..a91d19d 100644 --- a/src/main/java/cc/polyfrost/oneconfig/gui/elements/text/TextInputField.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/text/TextInputField.java @@ -4,10 +4,13 @@ import cc.polyfrost.oneconfig.config.OneConfigConfig; import cc.polyfrost.oneconfig.gui.elements.BasicElement; import cc.polyfrost.oneconfig.lwjgl.RenderManager; import cc.polyfrost.oneconfig.lwjgl.font.Fonts; +import cc.polyfrost.oneconfig.lwjgl.image.SVGs; import cc.polyfrost.oneconfig.lwjgl.scissor.Scissor; import cc.polyfrost.oneconfig.lwjgl.scissor.ScissorManager; import cc.polyfrost.oneconfig.utils.InputUtils; +import cc.polyfrost.oneconfig.utils.TextUtils; import gg.essential.universal.UKeyboard; +import kotlin.Pair; import org.jetbrains.annotations.NotNull; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; @@ -15,6 +18,8 @@ import org.lwjgl.input.Mouse; import java.awt.*; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.StringSelection; +import java.util.ArrayList; +import java.util.Map; public class TextInputField extends BasicElement { @@ -33,17 +38,25 @@ public class TextInputField extends BasicElement { protected boolean onlyNums = false; protected boolean errored = false; protected boolean centered = false; + private int lines = 1; + protected SVGs icon; + protected ArrayList<String> wrappedText = null; - public TextInputField(int width, int height, String defaultText, boolean multiLine, boolean password) { + public TextInputField(int width, int height, String defaultText, boolean multiLine, boolean password, SVGs icon) { super(width, height, false); this.multiLine = multiLine; this.defaultText = defaultText; this.password = password; this.input = ""; + this.icon = icon; + } + + public TextInputField(int width, int height, String defaultText, boolean multiLine, boolean password) { + this(width, height, defaultText, multiLine, password, null); } public TextInputField(int width, int height, boolean centered, String defaultText) { - this(width, height, defaultText, false, false); + this(width, height, defaultText, false, false, null); this.centered = centered; } @@ -99,9 +112,20 @@ public class TextInputField extends BasicElement { if (prevCaret > input.length()) prevCaret = input.length(); if (caretPos < 0) caretPos = 0; if (prevCaret < 0) prevCaret = 0; + if (icon != null) { + RenderManager.drawSvg(vg, icon, x + 12, y + height / 2f - 12f, 24, 24, color); + x += 32; + this.x = x; + } float width; StringBuilder s = new StringBuilder(); - if (!password) { + if (multiLine) { + wrappedText = TextUtils.wrapText(vg, input, this.width - 24, 14f, Fonts.REGULAR); + lines = wrappedText.size(); + if (!toggled) caretPos = wrappedText.get(wrappedText.size() - 1).length(); + int caretLine = getCaretLine(caretPos); + width = RenderManager.getTextWidth(vg, wrappedText.get(caretLine).substring(0, getLineCaret(caretPos, caretLine)), 14f, Fonts.REGULAR); + } else if (!password) { width = RenderManager.getTextWidth(vg, input.substring(0, caretPos), 14f, Fonts.REGULAR); } else { for (int i = 0; i < input.length(); i++) { @@ -113,7 +137,10 @@ public class TextInputField extends BasicElement { while (Mouse.next()) { if (Mouse.getEventButtonState()) { if (Mouse.getEventButton() == 0) { - prevCaret = calculatePos(InputUtils.mouseX()); + if (multiLine) { + int caretLine = Math.max(0, Math.min(wrappedText.size() - 1, (int) Math.floor((InputUtils.mouseY() - y - 10) / 24f))); + caretPos = calculatePos(InputUtils.mouseX(), wrappedText.get(caretLine)); + } else prevCaret = calculatePos(InputUtils.mouseX(), input); if (System.currentTimeMillis() - clickTimeD1 < 300) { onDoubleClick(); isDoubleClick = true; @@ -142,7 +169,10 @@ public class TextInputField extends BasicElement { } if (hovered) { if (Mouse.isButtonDown(0) && !isDoubleClick) { - caretPos = calculatePos(InputUtils.mouseX()); + if (multiLine) { + int caretLine = Math.max(0, Math.min(wrappedText.size() - 1, (int) Math.floor((InputUtils.mouseY() - y - 10) / 24f))); + caretPos = calculatePos(InputUtils.mouseX(), wrappedText.get(caretLine)); + } else caretPos = calculatePos(InputUtils.mouseX(), input); if (caretPos > prevCaret) { if (!centered) start = x + 12 + this.getTextWidth(vg, input.substring(0, prevCaret)); else @@ -161,7 +191,10 @@ public class TextInputField extends BasicElement { if (toggled) { - if (!centered) { + if (multiLine) { + int lineY = y + 20 + getCaretLine(caretPos) * 24; + RenderManager.drawLine(vg, x + width + 12, lineY - 10, x + width + 12, lineY + 10, 1, OneConfigConfig.WHITE); + } else 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); @@ -170,7 +203,9 @@ public class TextInputField extends BasicElement { if (input.equals("")) { - if (!centered) { + if (multiLine) { + RenderManager.drawString(vg, defaultText, x + 12, y + 16, color, 14f, Fonts.REGULAR); + } else if (!centered) { RenderManager.drawString(vg, defaultText, x + 12, y + height / 2f + 1, color, 14f, Fonts.REGULAR); } else { RenderManager.drawString(vg, defaultText, x + this.width / 2f - halfTextWidth, y + height / 2f + 1, color, 14f, Fonts.REGULAR); @@ -178,7 +213,13 @@ public class TextInputField extends BasicElement { } if (!password) { - if (!centered) { + if (multiLine) { + int textY = y + 20; + for (String line : wrappedText) { + RenderManager.drawString(vg, line, x + 12, textY, color, 14f, Fonts.REGULAR); + textY += 24; + } + } else if (!centered) { RenderManager.drawString(vg, input, x + 12, y + height / 2f + 1, color, 14f, Fonts.REGULAR); } else { RenderManager.drawString(vg, input, x + this.width / 2f - halfTextWidth, y + height / 2f + 1, color, 14f, Fonts.REGULAR); @@ -190,6 +231,7 @@ public class TextInputField extends BasicElement { } catch (Exception e) { e.printStackTrace(); } + } public void keyTyped(char c, int key) { @@ -345,12 +387,7 @@ public class TextInputField extends BasicElement { if (UKeyboard.isCtrlKeyDown()) return; if (isAllowedCharacter(c)) { if (selectedText != null) { - if (caretPos > prevCaret) { - input = input.substring(0, prevCaret) + input.substring(prevCaret, caretPos); - caretPos = prevCaret; - } else { - input = input.substring(0, caretPos) + input.substring(caretPos, prevCaret); - } + if (caretPos > prevCaret) caretPos = prevCaret; if (selectedText.equals(input)) { input = ""; } @@ -390,16 +427,16 @@ public class TextInputField extends BasicElement { end = this.getTextWidth(vg, input.substring(prevCaret, caretPos)); } - private int calculatePos(int pos) { + private int calculatePos(int pos, String string) { if (centered) pos -= 12; String s1 = ""; int i; - for (char c : input.toCharArray()) { + for (char c : string.toCharArray()) { if (pos - x - 12 < 0) { return 0; } - if (pos - x - 12 > this.getTextWidth(vg, input)) { - return input.length(); + if (pos - x - 12 > this.getTextWidth(vg, string)) { + return string.length(); } s1 += c; i = (int) this.getTextWidth(vg, s1); @@ -411,7 +448,6 @@ public class TextInputField extends BasicElement { } public void onClose() { - } private float getTextWidth(long vg, String s) { @@ -426,7 +462,49 @@ public class TextInputField extends BasicElement { } } + private int getCaretLine(int caret) { + int pos = 0; + for (int i = 0; i < wrappedText.size(); i++) { + String text = wrappedText.get(i); + float length = RenderManager.getTextWidth(vg, text, 14.0f, Fonts.REGULAR); + pos += length; + if (pos < caret) continue; + return i; + } + return 0; + } + + private float getCaretX(int caret) { + int pos = 0; + for (String text : wrappedText) { + float length = RenderManager.getTextWidth(vg, text, 14.0f, Fonts.REGULAR); + if (pos + length < caret) { + pos += length; + continue; + } + return RenderManager.getTextWidth(vg, text.substring(0, caret - pos), 14.0f, Fonts.REGULAR); + } + return 0; + } + + private int getLineCaret(int caret, int line) { + int pos = 0; + for (String text : wrappedText) { + float length = RenderManager.getTextWidth(vg, text, 14.0f, Fonts.REGULAR); + if (pos + length < caret) { + pos += length; + continue; + } + return caret - pos; + } + return 0; + } + public static boolean isAllowedCharacter(char character) { return character != 167 && character >= ' ' && character != 127; } + + public int getLines() { + return lines; + } } diff --git a/src/main/java/cc/polyfrost/oneconfig/lwjgl/RenderManager.java b/src/main/java/cc/polyfrost/oneconfig/lwjgl/RenderManager.java index 153fc52..9d6763f 100644 --- a/src/main/java/cc/polyfrost/oneconfig/lwjgl/RenderManager.java +++ b/src/main/java/cc/polyfrost/oneconfig/lwjgl/RenderManager.java @@ -379,43 +379,9 @@ public final class RenderManager { drawSvg(vg, icon, centerX - iconSize / 2f, centerY - iconSize / 2f, iconSize, iconSize); } - /*public static void drawSvg(long vg, String filename) { - if (ImageLoader.INSTANCE.loadSVGImage(filename)) { - try { - NSVGImage image = ImageLoader.INSTANCE.getSVG(filename); - NSVGShape shape = image.shapes(); - NSVGPath path = shape.paths(); - while (shape.address() != 0) { - while (path.address() != 0) { - nvgBeginPath(vg); - nvgFillColor(vg, color(vg, new Color(255, 255, 255).getRGB())); - nvgStrokeColor(vg, color(vg, new Color(255, 255, 255).getRGB())); - nvgStrokeWidth(vg, shape.strokeWidth()); - FloatBuffer points = path.pts(); - nvgMoveTo(vg, points.get(), points.get()); - while (points.remaining() >= 6){ - nvgBezierTo(vg, points.get(), points.get(), points.get(), points.get(), points.get(), points.get()); - } - if (path.closed() == 1) { - nvgLineTo(vg, points.get(0), points.get(1)); - } - nvgStroke(vg); - nvgClosePath(vg); - path = path.next(); - } - shape = shape.next(); - } - path.free(); - shape.free(); - } catch (Exception e) { - e.printStackTrace(); - } - } - }*/ - // gl - public static void drawScaledString(String text, float x, float y, int color, boolean shadow, float scale) { //todo replace eventually with either nanovg or UMatrixStack + public static void drawScaledString(String text, float x, float y, int color, boolean shadow, float scale) { UGraphics.GL.pushMatrix(); UGraphics.GL.scale(scale, scale, 1); UMinecraft.getFontRenderer().drawString(text, x * (1 / scale), y * (1 / scale), color, shadow); diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/TextUtils.java b/src/main/java/cc/polyfrost/oneconfig/utils/TextUtils.java new file mode 100644 index 0000000..f574ea1 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/utils/TextUtils.java @@ -0,0 +1,32 @@ +package cc.polyfrost.oneconfig.utils; + +import cc.polyfrost.oneconfig.lwjgl.RenderManager; +import cc.polyfrost.oneconfig.lwjgl.font.Fonts; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class TextUtils { + + public static ArrayList<String> wrapText(long vg, String text, float maxWidth, float fontSize, Fonts font) { + ArrayList<String> wrappedText = new ArrayList<>(); + List<String> split = Arrays.asList(text.split(" ")); + for (int i = split.size(); i >= 0; i--) { + String textPart = String.join(" ", split.subList(0, i)); + float textWidth = RenderManager.getTextWidth(vg, textPart, fontSize, font); + if (textWidth > maxWidth) continue; + wrappedText.add(textPart); + if (i != split.size()) + wrappedText.addAll(wrapText(vg, String.join(" ", split.subList(i, split.size())), maxWidth, fontSize, font)); + break; + } + if (text.endsWith(" ")) { + String lastLine = wrappedText.get(wrappedText.size() - 1); + lastLine += " "; + wrappedText.remove(wrappedText.size() - 1); + wrappedText.add(lastLine); + } + return wrappedText; + } +} |