Files
AdvancedScripts/src/main/java/de/zonlykroks/advancedscripts/screen/ScriptEditScreen.java
2022-12-25 10:11:40 +01:00

277 lines
8.7 KiB
Java

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<String> 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<Token> 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);
}
}