package me.shedaniel.rei.gui.widget; import com.google.common.base.Predicates; import com.mojang.blaze3d.platform.GlStateManager; import net.minecraft.SharedConstants; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.FontRenderer; import net.minecraft.client.gui.Drawable; import net.minecraft.client.gui.Gui; import net.minecraft.client.render.BufferBuilder; import net.minecraft.client.render.Tessellator; import net.minecraft.client.render.VertexFormats; import net.minecraft.util.math.MathHelper; import java.awt.*; import java.util.ArrayList; import java.util.List; import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Predicate; public class TextFieldWidget extends Drawable implements IWidget { private final FontRenderer fontRenderer; private int width; private int height; private int x; private int y; private String text; private int maxLength; private int focusedTicks; private boolean hasBorder; private boolean field_2096; private boolean focused; private boolean editable; private boolean field_17037; private int field_2103; private int cursorMax; private int cursorMin; private int field_2100; private int field_2098; private boolean visible; private String suggestion; private Consumer changedListener; private Predicate textPredicate; private BiFunction field_2099; public TextFieldWidget(Rectangle rectangle) { this(rectangle.x, rectangle.y, rectangle.width, rectangle.height); } public TextFieldWidget(int x, int y, int width, int height) { this.text = ""; this.maxLength = 32; this.hasBorder = true; this.field_2096 = true; this.editable = true; this.field_2100 = 14737632; this.field_2098 = 7368816; this.visible = true; this.textPredicate = Predicates.alwaysTrue(); this.field_2099 = (string_1, integer_1) -> { return string_1; }; this.fontRenderer = MinecraftClient.getInstance().fontRenderer; this.x = x; this.y = y; this.width = width; this.height = height; } public Rectangle getBounds() { return new Rectangle(x, y, width, height); } public void setBounds(Rectangle rectangle) { this.x = rectangle.x; this.y = rectangle.y; this.width = rectangle.width; this.height = rectangle.height; } public void setChangedListener(Consumer biConsumer_1) { this.changedListener = biConsumer_1; } public void method_1854(BiFunction biFunction_1) { this.field_2099 = biFunction_1; } public void tick() { ++this.focusedTicks; } public String getText() { return this.text; } public void setText(String string_1) { if (this.textPredicate.test(string_1)) { if (string_1.length() > this.maxLength) { this.text = string_1.substring(0, this.maxLength); } else { this.text = string_1; } this.onChanged(string_1); this.method_1872(); } } public String getSelectedText() { int int_1 = this.cursorMax < this.cursorMin ? this.cursorMax : this.cursorMin; int int_2 = this.cursorMax < this.cursorMin ? this.cursorMin : this.cursorMax; return this.text.substring(int_1, int_2); } public void method_1890(Predicate predicate_1) { this.textPredicate = predicate_1; } public void addText(String string_1) { String string_2 = ""; String string_3 = SharedConstants.stripInvalidChars(string_1); int int_1 = this.cursorMax < this.cursorMin ? this.cursorMax : this.cursorMin; int int_2 = this.cursorMax < this.cursorMin ? this.cursorMin : this.cursorMax; int int_3 = this.maxLength - this.text.length() - (int_1 - int_2); if (!this.text.isEmpty()) { string_2 = string_2 + this.text.substring(0, int_1); } int int_5; if (int_3 < string_3.length()) { string_2 = string_2 + string_3.substring(0, int_3); int_5 = int_3; } else { string_2 = string_2 + string_3; int_5 = string_3.length(); } if (!this.text.isEmpty() && int_2 < this.text.length()) { string_2 = string_2 + this.text.substring(int_2); } if (this.textPredicate.test(string_2)) { this.text = string_2; this.setCursor(int_1 + int_5); this.method_1884(this.cursorMax); this.onChanged(this.text); } } public void onChanged(String string_1) { if (this.changedListener != null) { this.changedListener.accept(string_1); } } private void method_16873(int int_1) { if (Gui.isControlPressed()) { this.method_1877(int_1); } else { this.method_1878(int_1); } } public void method_1877(int int_1) { if (!this.text.isEmpty()) { if (this.cursorMin != this.cursorMax) { this.addText(""); } else { this.method_1878(this.method_1853(int_1) - this.cursorMax); } } } public void method_1878(int int_1) { if (!this.text.isEmpty()) { if (this.cursorMin != this.cursorMax) { this.addText(""); } else { boolean boolean_1 = int_1 < 0; int int_2 = boolean_1 ? this.cursorMax + int_1 : this.cursorMax; int int_3 = boolean_1 ? this.cursorMax : this.cursorMax + int_1; String string_1 = ""; if (int_2 >= 0) { string_1 = this.text.substring(0, int_2); } if (int_3 < this.text.length()) { string_1 = string_1 + this.text.substring(int_3); } if (this.textPredicate.test(string_1)) { this.text = string_1; if (boolean_1) { this.moveCursor(int_1); } this.onChanged(this.text); } } } } public int method_1853(int int_1) { return this.method_1869(int_1, this.getCursor()); } public int method_1869(int int_1, int int_2) { return this.method_1864(int_1, int_2, true); } public int method_1864(int int_1, int int_2, boolean boolean_1) { int int_3 = int_2; boolean boolean_2 = int_1 < 0; int int_4 = Math.abs(int_1); for(int int_5 = 0; int_5 < int_4; ++int_5) { if (!boolean_2) { int int_6 = this.text.length(); int_3 = this.text.indexOf(32, int_3); if (int_3 == -1) { int_3 = int_6; } else { while (boolean_1 && int_3 < int_6 && this.text.charAt(int_3) == ' ') { ++int_3; } } } else { while (boolean_1 && int_3 > 0 && this.text.charAt(int_3 - 1) == ' ') { --int_3; } while (int_3 > 0 && this.text.charAt(int_3 - 1) != ' ') { --int_3; } } } return int_3; } public void moveCursor(int int_1) { this.method_1883(this.cursorMax + int_1); } public void method_1883(int int_1) { this.setCursor(int_1); if (!this.field_17037) { this.method_1884(this.cursorMax); } this.onChanged(this.text); } public void method_1870() { this.method_1883(0); } public void method_1872() { this.method_1883(this.text.length()); } public boolean keyPressed(int int_1, int int_2, int int_3) { if (this.isVisible() && this.isFocused()) { this.field_17037 = Gui.isShiftPressed(); if (Gui.isSelectAllShortcutPressed(int_1)) { this.method_1872(); this.method_1884(0); return true; } else if (Gui.isCopyShortcutPressed(int_1)) { MinecraftClient.getInstance().keyboard.setClipboard(this.getSelectedText()); return true; } else if (Gui.isPasteShortcutPressed(int_1)) { if (this.editable) { this.addText(MinecraftClient.getInstance().keyboard.getClipboard()); } return true; } else if (Gui.isCutShortcutPressed(int_1)) { MinecraftClient.getInstance().keyboard.setClipboard(this.getSelectedText()); if (this.editable) { this.addText(""); } return true; } else { switch (int_1) { case 259: if (this.editable) { this.method_16873(-1); } return true; case 260: case 264: case 265: case 266: case 267: default: return int_1 != 256; case 261: if (this.editable) { this.method_16873(1); } return true; case 262: if (Gui.isControlPressed()) { this.method_1883(this.method_1853(1)); } else { this.moveCursor(1); } return true; case 263: if (Gui.isControlPressed()) { this.method_1883(this.method_1853(-1)); } else { this.moveCursor(-1); } return true; case 268: this.method_1870(); return true; case 269: this.method_1872(); return true; } } } else { return false; } } public boolean charTyped(char char_1, int int_1) { if (this.isVisible() && this.isFocused()) { if (SharedConstants.isValidChar(char_1)) { if (this.editable) { this.addText(Character.toString(char_1)); } return true; } else { return false; } } else { return false; } } @Override public List getListeners() { return new ArrayList<>(); } public boolean mouseClicked(double double_1, double double_2, int int_1) { if (!this.isVisible()) { return false; } else { boolean boolean_1 = double_1 >= (double) this.x && double_1 < (double) (this.x + this.width) && double_2 >= (double) this.y && double_2 < (double) (this.y + this.height); if (this.field_2096) { this.setFocused(boolean_1); } if (this.focused && boolean_1 && int_1 == 0) { int int_2 = MathHelper.floor(double_1) - this.x; if (this.hasBorder) { int_2 -= 4; } String string_1 = this.fontRenderer.method_1714(this.text.substring(this.field_2103), this.method_1859()); this.method_1883(this.fontRenderer.method_1714(string_1, int_2).length() + this.field_2103); return true; } else { return false; } } } public void draw(int int_1, int int_2, float float_1) { if (this.isVisible()) { if (this.hasBorder()) { drawRect(this.x - 1, this.y - 1, this.x + this.width + 1, this.y + this.height + 1, -6250336); drawRect(this.x, this.y, this.x + this.width, this.y + this.height, -16777216); } int int_3 = this.editable ? this.field_2100 : this.field_2098; int int_4 = this.cursorMax - this.field_2103; int int_5 = this.cursorMin - this.field_2103; String string_1 = this.fontRenderer.method_1714(this.text.substring(this.field_2103), this.method_1859()); boolean boolean_1 = int_4 >= 0 && int_4 <= string_1.length(); boolean boolean_2 = this.focused && this.focusedTicks / 6 % 2 == 0 && boolean_1; int int_6 = this.hasBorder ? this.x + 4 : this.x; int int_7 = this.hasBorder ? this.y + (this.height - 8) / 2 : this.y; int int_8 = int_6; if (int_5 > string_1.length()) { int_5 = string_1.length(); } if (!string_1.isEmpty()) { String string_2 = boolean_1 ? string_1.substring(0, int_4) : string_1; int_8 = this.fontRenderer.drawWithShadow((String) this.field_2099.apply(string_2, this.field_2103), (float) int_6, (float) int_7, int_3); } boolean boolean_3 = this.cursorMax < this.text.length() || this.text.length() >= this.getMaxLength(); int int_9 = int_8; if (!boolean_1) { int_9 = int_4 > 0 ? int_6 + this.width : int_6; } else if (boolean_3) { int_9 = int_8 - 1; --int_8; } if (!string_1.isEmpty() && boolean_1 && int_4 < string_1.length()) { this.fontRenderer.drawWithShadow((String) this.field_2099.apply(string_1.substring(int_4), this.cursorMax), (float) int_8, (float) int_7, int_3); } if (!boolean_3 && this.suggestion != null) { this.fontRenderer.drawWithShadow(this.suggestion, (float) (int_9 - 1), (float) int_7, -8355712); } int var10002; int var10003; if (boolean_2) { if (boolean_3) { int var10001 = int_7 - 1; var10002 = int_9 + 1; var10003 = int_7 + 1; this.fontRenderer.getClass(); Drawable.drawRect(int_9, var10001, var10002, var10003 + 9, -3092272); } else { this.fontRenderer.drawWithShadow("_", (float) int_9, (float) int_7, int_3); } } if (int_5 != int_4) { int int_10 = int_6 + this.fontRenderer.getStringWidth(string_1.substring(0, int_5)); var10002 = int_7 - 1; var10003 = int_10 - 1; int var10004 = int_7 + 1; this.fontRenderer.getClass(); this.method_1886(int_9, var10002, var10003, var10004 + 9); } } } private void method_1886(int int_1, int int_2, int int_3, int int_4) { int int_6; if (int_1 < int_3) { int_6 = int_1; int_1 = int_3; int_3 = int_6; } if (int_2 < int_4) { int_6 = int_2; int_2 = int_4; int_4 = int_6; } if (int_3 > this.x + this.width) { int_3 = this.x + this.width; } if (int_1 > this.x + this.width) { int_1 = this.x + this.width; } Tessellator tessellator_1 = Tessellator.getInstance(); BufferBuilder bufferBuilder_1 = tessellator_1.getBufferBuilder(); GlStateManager.color4f(0.0F, 0.0F, 255.0F, 255.0F); GlStateManager.disableTexture(); GlStateManager.enableColorLogicOp(); GlStateManager.logicOp(GlStateManager.LogicOp.OR_REVERSE); bufferBuilder_1.begin(7, VertexFormats.POSITION); bufferBuilder_1.vertex((double) int_1, (double) int_4, 0.0D).next(); bufferBuilder_1.vertex((double) int_3, (double) int_4, 0.0D).next(); bufferBuilder_1.vertex((double) int_3, (double) int_2, 0.0D).next(); bufferBuilder_1.vertex((double) int_1, (double) int_2, 0.0D).next(); tessellator_1.draw(); GlStateManager.disableColorLogicOp(); GlStateManager.enableTexture(); } public int getMaxLength() { return this.maxLength; } public void setMaxLength(int int_1) { this.maxLength = int_1; if (this.text.length() > int_1) { this.text = this.text.substring(0, int_1); this.onChanged(this.text); } } public int getCursor() { return this.cursorMax; } public void setCursor(int int_1) { this.cursorMax = MathHelper.clamp(int_1, 0, this.text.length()); } public boolean hasBorder() { return this.hasBorder; } public void setHasBorder(boolean boolean_1) { this.hasBorder = boolean_1; } public void method_1868(int int_1) { this.field_2100 = int_1; } public void method_1860(int int_1) { this.field_2098 = int_1; } public void setHasFocus(boolean boolean_1) { this.setFocused(boolean_1); } public boolean hasFocus() { return true; } public boolean isFocused() { return this.focused; } public void setFocused(boolean boolean_1) { if (boolean_1 && !this.focused) { this.focusedTicks = 0; } this.focused = boolean_1; } public void setIsEditable(boolean boolean_1) { this.editable = boolean_1; } public int method_1859() { return this.hasBorder() ? this.width - 8 : this.width; } public void method_1884(int int_1) { int int_2 = this.text.length(); this.cursorMin = MathHelper.clamp(int_1, 0, int_2); if (this.fontRenderer != null) { if (this.field_2103 > int_2) { this.field_2103 = int_2; } int int_3 = this.method_1859(); String string_1 = this.fontRenderer.method_1714(this.text.substring(this.field_2103), int_3); int int_4 = string_1.length() + this.field_2103; if (this.cursorMin == this.field_2103) { this.field_2103 -= this.fontRenderer.method_1711(this.text, int_3, true).length(); } if (this.cursorMin > int_4) { this.field_2103 += this.cursorMin - int_4; } else if (this.cursorMin <= this.field_2103) { this.field_2103 -= this.field_2103 - this.cursorMin; } this.field_2103 = MathHelper.clamp(this.field_2103, 0, int_2); } } public void method_1856(boolean boolean_1) { this.field_2096 = boolean_1; } public boolean isVisible() { return this.visible; } public void setVisible(boolean boolean_1) { this.visible = boolean_1; } public void setSuggestion(String string_1) { this.suggestion = string_1; } public int method_1889(int int_1) { return int_1 > this.text.length() ? this.x : this.x + this.fontRenderer.getStringWidth(this.text.substring(0, int_1)); } public void setX(int int_1) { this.x = int_1; } }