Make ore dictionary filter editor multiline

This commit is contained in:
DreamYao520 committed 2026-09-25 06:05:42 +08:00
1 parent 151550f6d5
commit 7b13911080
3 files changed
+261 -6

No files matched your search

@@ -2,16 +2,18 @@ package appeng.client.gui.implementations;
import java.io.IOException;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import appeng.client.gui.GuiSub;
import appeng.client.gui.widgets.IDropToFillTextField;
import appeng.client.gui.widgets.MEGuiTextField;
import appeng.client.gui.widgets.MEGuiMultilineTextField;
import appeng.container.implementations.ContainerOreFilter;
import appeng.core.AELog;
import appeng.core.localization.ColorUtils;
@@ -25,7 +27,7 @@ import appeng.util.prioitylist.OreFilteredList.OreFilterTextFormatter;
public class GuiOreFilter extends GuiSub implements IDropToFillTextField {
private MEGuiTextField textField;
private MEGuiMultilineTextField textField;
private boolean useNEIFilter = false;
private long lastclicktime;
@@ -33,8 +35,9 @@ public class GuiOreFilter extends GuiSub implements IDropToFillTextField {
public GuiOreFilter(InventoryPlayer ip, IOreFilterable obj) {
super(new ContainerOreFilter(ip, obj));
this.xSize = 256;
this.ySize = 180;
this.textField = new MEGuiTextField(231, 12) {
this.textField = new MEGuiMultilineTextField(231, 126) {
@Override
public void onTextChange(final String oldText) {
@@ -56,10 +59,12 @@ public class GuiOreFilter extends GuiSub implements IDropToFillTextField {
@Override
public void initGui() {
this.ySize = Math.max(72, Math.min(180, this.height - 24));
super.initGui();
this.textField.x = this.guiLeft + 12;
this.textField.y = this.guiTop + 35;
this.textField.h = this.ySize - 54;
this.textField.setFocused(true);
((ContainerOreFilter) this.inventorySlots).setTextField(this.textField);
@@ -100,7 +105,13 @@ public class GuiOreFilter extends GuiSub implements IDropToFillTextField {
@Override
public void drawBG(int offsetX, int offsetY, int mouseX, int mouseY) {
this.bindTexture("guis/renamer.png");
this.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize);
this.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, 34);
GL11.glPushMatrix();
GL11.glTranslatef(offsetX, offsetY + 34, 0);
GL11.glScalef(1, this.ySize - 47, 1);
this.drawTexturedModalRect(0, 0, 0, 33, this.xSize, 1);
GL11.glPopMatrix();
this.drawTexturedModalRect(offsetX, offsetY + this.ySize - 13, 0, 47, this.xSize, 13);
this.textField.drawTextBox();
if (this.useNEIFilter) {
@@ -124,6 +135,15 @@ public class GuiOreFilter extends GuiSub implements IDropToFillTextField {
}
}
@Override
protected boolean mouseWheelEvent(int mouseX, int mouseY, int wheel) {
if (this.textField.isMouseIn(mouseX, mouseY)) {
this.textField.scroll(wheel);
return true;
}
return super.mouseWheelEvent(mouseX, mouseY, wheel);
}
@Override
protected void mouseClicked(final int xCoord, final int yCoord, final int btn) {
@@ -139,9 +159,15 @@ public class GuiOreFilter extends GuiSub implements IDropToFillTextField {
super.mouseClicked(xCoord, yCoord, btn);
}
@Override
protected void mouseClickMove(int mouseX, int mouseY, int button, long elapsedTime) {
if (button == 0 && this.textField.isFocused()) this.textField.mouseDragged(mouseX, mouseY);
super.mouseClickMove(mouseX, mouseY, button, elapsedTime);
}
@Override
protected void keyTyped(final char character, final int key) {
if (key == Keyboard.KEY_RETURN || key == Keyboard.KEY_NUMPADENTER) {
if ((key == Keyboard.KEY_RETURN || key == Keyboard.KEY_NUMPADENTER) && !GuiScreen.isShiftKeyDown()) {
try {
NetworkHandler.instance.sendToServer(new PacketValueConfig("OreFilter", this.textField.getText()));
} catch (IOException e) {
@@ -0,0 +1,229 @@
package appeng.client.gui.widgets;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiTextField;
import org.lwjgl.input.Keyboard;
import appeng.core.localization.ColorUtils;
import codechicken.nei.FormattedTextField.TextFormatter;
public class MEGuiMultilineTextField extends MEGuiTextField {
private final FontRenderer font = Minecraft.getMinecraft().fontRenderer;
private TextFormatter formatter;
private int scrollLine;
public MEGuiMultilineTextField(int width, int height) {
super(width, height);
}
@Override
public void setFormatter(Object formatter) {
super.setFormatter(formatter);
if (formatter instanceof TextFormatter textFormatter) this.formatter = textFormatter;
}
@Override
public void drawTextBox() {
GuiTextField.drawRect(
x + 1,
y + 1,
x + w - 1,
y + h - 1,
isFocused() ? ColorUtils.searchboxFocused.getColor() : ColorUtils.searchboxUnfocused.getColor());
String text = getText();
List<Line> lines = wrap(text);
scrollLine = Math.min(scrollLine, Math.max(0, lines.size() - visibleLines()));
int selectionStart = Math.min(field.getCursorPosition(), field.getSelectionEnd());
int selectionEnd = Math.max(field.getCursorPosition(), field.getSelectionEnd());
for (int row = scrollLine; row < Math.min(lines.size(), scrollLine + visibleLines()); row++) {
Line line = lines.get(row);
int textY = y + 3 + (row - scrollLine) * lineHeight();
if (selectionStart < line.end && selectionEnd > line.start) {
int from = Math.max(selectionStart, line.start);
int to = Math.min(selectionEnd, line.end);
GuiTextField.drawRect(
x + 3 + font.getStringWidth(text.substring(line.start, from)),
textY,
x + 3 + font.getStringWidth(text.substring(line.start, to)),
textY + font.FONT_HEIGHT,
0x663D89C9);
}
String content = text.substring(line.start, line.end);
font.drawString(
formatter == null ? content : formatter.format(content),
x + 3,
textY,
ColorUtils.searchboxText.getColor());
}
if (isFocused() && System.currentTimeMillis() / 500 % 2 == 0) {
int cursor = field.getSelectionEnd();
int row = cursorLine(lines, cursor);
if (row >= scrollLine && row < scrollLine + visibleLines()) {
Line line = lines.get(row);
int cursorX = x + 3 + font.getStringWidth(text.substring(line.start, Math.min(cursor, line.end)));
int cursorY = y + 3 + (row - scrollLine) * lineHeight();
GuiTextField.drawRect(cursorX, cursorY, cursorX + 1, cursorY + font.FONT_HEIGHT, 0xFFFFFFFF);
}
}
}
@Override
public void mouseClicked(int mouseX, int mouseY, int button) {
if (!isMouseIn(mouseX, mouseY)) {
setFocused(false);
return;
}
setFocused(true);
if (button == 1) {
setText("");
} else if (button == 0) {
int position = positionAt(mouseX, mouseY);
if (GuiScreen.isShiftKeyDown()) field.setSelectionPos(position);
else field.setCursorPosition(position);
}
ensureCursorVisible();
}
public void mouseDragged(int mouseX, int mouseY) {
if (isFocused()) field.setSelectionPos(positionAt(mouseX, mouseY));
}
public void scroll(int wheel) {
scrollLine = Math.max(
0,
Math.min(wrap(getText()).size() - visibleLines(), scrollLine - (wheel > 0 ? 3 : -3)));
}
@Override
public boolean textboxKeyTyped(char character, int key) {
if (!isFocused()) return false;
if ((key == Keyboard.KEY_RETURN || key == Keyboard.KEY_NUMPADENTER) && GuiScreen.isShiftKeyDown()) {
insert("\n");
return true;
}
if (GuiScreen.isCtrlKeyDown() && key == Keyboard.KEY_V) {
String clipboard = GuiScreen.getClipboardString();
if (clipboard != null) insert(clipboard.replace("\r\n", "\n").replace('\r', '\n'));
return true;
}
if (key == Keyboard.KEY_UP || key == Keyboard.KEY_DOWN) {
moveVertically(key == Keyboard.KEY_UP ? -1 : 1);
return true;
}
boolean handled = super.textboxKeyTyped(character, key);
if (handled) ensureCursorVisible();
return handled;
}
@Override
public void setText(String text, boolean ignoreTrigger) {
super.setText(text, ignoreTrigger);
ensureCursorVisible();
}
private void insert(String insertion) {
String oldText = getText();
int start = Math.min(field.getCursorPosition(), field.getSelectionEnd());
int end = Math.max(field.getCursorPosition(), field.getSelectionEnd());
int available = getMaxStringLength() - oldText.length() + end - start;
if (available <= 0) return;
if (insertion.length() > available) insertion = insertion.substring(0, available);
field.setText(oldText.substring(0, start) + insertion + oldText.substring(end));
field.setCursorPosition(start + insertion.length());
onTextChange(oldText);
ensureCursorVisible();
}
private void moveVertically(int direction) {
String text = getText();
List<Line> lines = wrap(text);
int cursor = field.getSelectionEnd();
Line current = lines.get(cursorLine(lines, cursor));
int targetRow = Math.max(0, Math.min(lines.size() - 1, cursorLine(lines, cursor) + direction));
int column = font.getStringWidth(text.substring(current.start, Math.min(cursor, current.end)));
int target = positionInLine(lines.get(targetRow), x + 3 + column);
if (GuiScreen.isShiftKeyDown()) field.setSelectionPos(target);
else field.setCursorPosition(target);
ensureCursorVisible();
}
private void ensureCursorVisible() {
List<Line> lines = wrap(getText());
int row = cursorLine(lines, field.getSelectionEnd());
if (row < scrollLine) scrollLine = row;
if (row >= scrollLine + visibleLines()) scrollLine = row - visibleLines() + 1;
}
private int positionAt(int mouseX, int mouseY) {
List<Line> lines = wrap(getText());
int row = Math.max(0, Math.min(lines.size() - 1, scrollLine + (mouseY - y - 3) / lineHeight()));
return positionInLine(lines.get(row), mouseX);
}
private int positionInLine(Line line, int mouseX) {
String text = getText();
for (int position = line.start; position < line.end; position++) {
int midpoint = x + 3 + font.getStringWidth(text.substring(line.start, position))
+ font.getCharWidth(text.charAt(position)) / 2;
if (mouseX < midpoint) return position;
}
return line.end;
}
private int cursorLine(List<Line> lines, int cursor) {
int row = 0;
for (int i = 1; i < lines.size() && lines.get(i).start <= cursor; i++) row = i;
return row;
}
private List<Line> wrap(String text) {
List<Line> lines = new ArrayList<>();
int start = 0;
while (true) {
int newline = text.indexOf('\n', start);
int end = newline < 0 ? text.length() : newline;
if (start == end) lines.add(new Line(start, end));
while (start < end) {
int length = Math.max(1, font.trimStringToWidth(text.substring(start, end), w - 6).length());
int next = Math.min(end, start + length);
lines.add(new Line(start, next));
start = next;
}
if (newline < 0) return lines;
start = newline + 1;
}
}
private int lineHeight() {
return font.FONT_HEIGHT + 2;
}
private int visibleLines() {
return Math.max(1, (h - 4) / lineHeight());
}
private static class Line {
final int start;
final int end;
Line(int start, int end) {
this.start = start;
this.end = end;
}
}
}
@@ -110,7 +110,7 @@ public class OreFilteredList implements IPartitionList<IAEItemStack> {
public static Predicate<IAEItemStack> makeFilter(String f) {
try {
Predicate<ItemStack> matcher = makeMatcher(f);
Predicate<ItemStack> matcher = makeMatcher(f.replace("\r", "").replace("\n", ""));
if (matcher == null) return null;
return new OreListMatcher(matcher);
} catch (Exception ex) {