package de.zonlykroks.advancedscripts.screen; import com.mojang.blaze3d.systems.RenderSystem; import de.zonlykroks.advancedscripts.lexer.ScriptColorizer; import de.zonlykroks.advancedscripts.lexer.Token; import de.zonlykroks.advancedscripts.lexer.TokenTypeColors; import net.minecraft.client.font.TextHandler; import net.minecraft.client.gui.DrawableHelper; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.BookScreen; import net.minecraft.client.render.GameRenderer; import net.minecraft.client.util.NarratorManager; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; import net.minecraft.text.Style; import net.minecraft.util.Hand; import org.apache.commons.lang3.mutable.MutableInt; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; public class ScriptEditScreen extends Screen { private PlayerEntity player; private ItemStack itemStack; private Hand hand; private List lines = new ArrayList<>(); private int cursorY = 0; private int cursorX = 0; private int tickCounter; public ScriptEditScreen(PlayerEntity player, ItemStack itemStack, Hand hand) { super(NarratorManager.EMPTY); this.player = player; this.itemStack = itemStack; this.hand = hand; NbtCompound nbtCompound = itemStack.getNbt(); if (nbtCompound != null) { BookScreen.filterPages(nbtCompound, s -> { lines.addAll(Arrays.asList(s.split("\n"))); }); } if (lines.isEmpty()) { lines.add(""); } } @Override public void tick() { super.tick(); ++this.tickCounter; } @Override public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { this.renderBackground(matrices); RenderSystem.setShader(GameRenderer::getPositionTexProgram); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); fill(matrices, 23, 23, this.width - 23, this.height - 72, TokenTypeColors.BACKGROUND); int lineNumberLength = textRenderer.getWidth(lines.size() + ""); // TODO: Implement text rendering int lineNumberText = 1; MutableInt lineNumber = new MutableInt(); TextHandler textHandler = this.textRenderer.getTextHandler(); for (int i = 0; i < lines.size(); i++) { String s = lines.get(i); if (lineNumber.getValue() * 9 + 25 > this.height - 75) { break; } // Line number this.textRenderer.draw(matrices, lineNumberText + "", 25 + lineNumberLength - textRenderer.getWidth(lineNumberText + ""), 25 + lineNumber.getValue() * 9, 0xFFFFFF); lineNumberText++; // Line text List tokens = ScriptColorizer.colorize(lineNumber.getValue(), s); AtomicInteger x = new AtomicInteger(25 + lineNumberLength + 5); for (Token token : tokens) { textHandler.wrapLines(token.text, this.width - x.get() - 25, Style.EMPTY, true, (style, start, end) -> { int y = lineNumber.getValue() * 9; if (y + 25 > this.height - 75) { return; } String line = token.text.substring(start, end); this.textRenderer.draw(matrices, line, x.get(), 25 + y, token.color); x.addAndGet(textRenderer.getWidth(line)); if (x.get() > this.width - 50 - lineNumberLength - 5) { x.set(25 + lineNumberLength + 5); lineNumber.increment(); } }); } lineNumber.increment(); } drawCursor(matrices, 25 + lineNumberLength + 5 + textRenderer.getWidth(lines.get(cursorY).substring(0, cursorX)), 25 + cursorY * 9, isAtEndOfLine()); super.render(matrices, mouseX, mouseY, delta); } private void drawCursor(MatrixStack matrices, int x, int y, boolean atEnd) { if (this.tickCounter / 6 % 2 == 0) { if (!atEnd) { int var10001 = x; int var10002 = y - 1; int var10003 = x + 1; int var10004 = y; Objects.requireNonNull(this.textRenderer); DrawableHelper.fill(matrices, var10001, var10002, var10003, var10004 + 9, 0xFFFFFFFF); } else { this.textRenderer.draw(matrices, "_", (float)x, (float)y, 0xFFFFFFFF); } } } @Override public boolean keyReleased(int keyCode, int scanCode, int modifiers) { if (super.keyReleased(keyCode, scanCode, modifiers)) { return true; } switch (keyCode) { case 257: case 335: newLine(); break; case 259: backspace(); break; case 261: delete(); break; case 262: moveCursor(1); break; case 263: moveCursor(-1); break; case 264: moveDown(); break; case 265: moveUp(); break; } return true; } @Override public boolean charTyped(char chr, int modifiers) { if (super.charTyped(chr, modifiers)) { return true; } if (insert(chr, modifiers)) { return true; } return true; } private boolean insert(char chr, int modifiers) { String line = lines.get(cursorY); if (cursorX == line.length()) { line += chr; } else { line = line.substring(0, cursorX) + chr + line.substring(cursorX); } lines.set(cursorY, line); cursorX++; return true; } private boolean newLine() { String line = lines.get(cursorY); String newLine = line.substring(cursorX); line = line.substring(0, cursorX); lines.set(cursorY, line); lines.add(cursorY + 1, newLine); cursorY++; cursorX = 0; return true; } private boolean backspace() { if (cursorX == 0) { if (cursorY == 0) { return true; } String line = lines.get(cursorY); String prevLine = lines.get(cursorY - 1); lines.set(cursorY - 1, prevLine + line); lines.remove(cursorY); cursorY--; cursorX = prevLine.length(); } else { String line = lines.get(cursorY); line = line.substring(0, cursorX - 1) + line.substring(cursorX); lines.set(cursorY, line); cursorX--; } return true; } private boolean delete() { String line = lines.get(cursorY); if (cursorX == line.length()) { if (cursorY == lines.size() - 1) { return true; } String nextLine = lines.get(cursorY + 1); lines.set(cursorY, line + nextLine); lines.remove(cursorY + 1); } else { line = line.substring(0, cursorX) + line.substring(cursorX + 1); lines.set(cursorY, line); } return true; } private boolean moveCursor(int offset) { String line = lines.get(cursorY); if (cursorX + offset < 0) { if (cursorY == 0) { return true; } cursorY--; cursorX = lines.get(cursorY).length(); } else if (cursorX + offset > line.length()) { if (cursorY == lines.size() - 1) { return true; } cursorY++; cursorX = 0; } else { cursorX += offset; } return true; } private boolean moveDown() { if (cursorY == lines.size() - 1) { return true; } cursorY++; cursorX = Math.min(cursorX, lines.get(cursorY).length()); return true; } private boolean moveUp() { if (cursorY == 0) { return true; } cursorY--; cursorX = Math.min(cursorX, lines.get(cursorY).length()); return true; } private boolean isAtEndOfLine() { return cursorX == lines.get(cursorY).length(); } @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { return super.mouseClicked(mouseX, mouseY, button); } }