Add selection and copy, paste and cut
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Dieser Commit ist enthalten in:
yoyosource 2022-12-28 11:30:12 +01:00
Ursprung a6e2fa7fc5
Commit 36151e3a46
2 geänderte Dateien mit 224 neuen und 48 gelöschten Zeilen

Datei anzeigen

@ -7,6 +7,7 @@ public class TokenTypeColors {
} }
public static final int BACKGROUND = 0xFF1E1F22; public static final int BACKGROUND = 0xFF1E1F22;
public static final int SELECTION = 0xFF23437F;
public static final int OTHER = 0xFFFFFFFF; public static final int OTHER = 0xFFFFFFFF;
public static final int ERROR = 0xFFAA0000; public static final int ERROR = 0xFFAA0000;

Datei anzeigen

@ -13,6 +13,7 @@ import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
import net.minecraft.client.gui.widget.PressableWidget; import net.minecraft.client.gui.widget.PressableWidget;
import net.minecraft.client.render.GameRenderer; import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.util.NarratorManager; import net.minecraft.client.util.NarratorManager;
import net.minecraft.client.util.SelectionManager;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@ -25,10 +26,7 @@ import net.minecraft.text.Text;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.mutable.MutableInt;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
public class ScriptEditScreen extends Screen { public class ScriptEditScreen extends Screen {
@ -42,6 +40,9 @@ public class ScriptEditScreen extends Screen {
private int cursorY = 0; private int cursorY = 0;
private int cursorX = 0; private int cursorX = 0;
private int savedCursorY = -1;
private int savedCursorX = -1;
private int tickCounter; private int tickCounter;
private int keyCode = -1; private int keyCode = -1;
@ -114,6 +115,17 @@ public class ScriptEditScreen extends Screen {
} }
} }
private void setClipboard(String clipboard) {
if (this.client != null) {
SelectionManager.setClipboard(this.client, clipboard);
}
}
private String getClipboard() {
return this.client != null ? SelectionManager.getClipboard(this.client) : "";
}
@Override @Override
public void tick() { public void tick() {
super.tick(); super.tick();
@ -132,6 +144,12 @@ public class ScriptEditScreen extends Screen {
int lineNumberLength = textRenderer.getWidth(lines.size() + ""); int lineNumberLength = textRenderer.getWidth(lines.size() + "");
boolean hasSelection = savedCursorY != -1 && savedCursorX != -1;
int minSelectionY = Math.min(cursorY, savedCursorY);
int maxSelectionY = Math.max(cursorY, savedCursorY);
int minSelectionX = minSelectionY == cursorY ? cursorX : savedCursorX;
int maxSelectionX = maxSelectionY == cursorY ? cursorX : savedCursorX;
int lineNumberText = scroll + 1; int lineNumberText = scroll + 1;
MutableInt lineNumber = new MutableInt(); MutableInt lineNumber = new MutableInt();
TextHandler textHandler = this.textRenderer.getTextHandler(); TextHandler textHandler = this.textRenderer.getTextHandler();
@ -147,8 +165,8 @@ public class ScriptEditScreen extends Screen {
} }
// Line number // Line number
int height = this.textRenderer.getWrappedLinesHeight(s, this.width - 50 - lineNumberLength - 5);
if (lineTooLong(s)) { if (lineTooLong(s)) {
int height = this.textRenderer.getWrappedLinesHeight(s, this.width - 50 - lineNumberLength - 5);
fill(matrices, 25 + lineNumberLength + 2, 25 + lineNumber.getValue() * 9, 25 + lineNumberLength + 3, 25 + lineNumber.getValue() * 9 + height, TokenTypeColors.ERROR); fill(matrices, 25 + lineNumberLength + 2, 25 + lineNumber.getValue() * 9, 25 + lineNumberLength + 3, 25 + lineNumber.getValue() * 9 + height, TokenTypeColors.ERROR);
} }
this.textRenderer.draw(matrices, lineNumberText + "", 25 + lineNumberLength - textRenderer.getWidth(lineNumberText + ""), 25 + lineNumber.getValue() * 9, 0xFFFFFF); this.textRenderer.draw(matrices, lineNumberText + "", 25 + lineNumberLength - textRenderer.getWidth(lineNumberText + ""), 25 + lineNumber.getValue() * 9, 0xFFFFFF);
@ -169,9 +187,37 @@ public class ScriptEditScreen extends Screen {
String line = token.text.substring(start, end); String line = token.text.substring(start, end);
int previousXIndex = currentXIndex.get(); int previousXIndex = currentXIndex.get();
currentXIndex.addAndGet(line.length()); currentXIndex.addAndGet(line.length());
if (hasSelection) {
int x1 = x.get();
int x2 = x.get() + textRenderer.getWidth(line);
if (finalI == minSelectionY) {
if (minSelectionX > currentXIndex.get()) {
x2 = 0;
} else if (minSelectionX <= currentXIndex.get() && minSelectionX >= previousXIndex) {
int startInLine = minSelectionX - previousXIndex;
x1 += textRenderer.getWidth(line.substring(0, startInLine));
}
}
if (finalI == maxSelectionY) {
if (maxSelectionX < previousXIndex) {
x2 = 0;
} else if (maxSelectionX <= currentXIndex.get()) {
int endInLine = maxSelectionX - previousXIndex;
x2 = x.get() + textRenderer.getWidth(line.substring(0, endInLine));
}
}
if (finalI >= minSelectionY && finalI <= maxSelectionY && x2 > x1) {
fill(matrices, x1, y + 25, x2, y + 25 + 9, TokenTypeColors.SELECTION);
}
}
if (finalI == cursorY && currentXIndex.get() >= cursorX && previousXIndex <= cursorX) { if (finalI == cursorY && currentXIndex.get() >= cursorX && previousXIndex <= cursorX) {
drawCursor(matrices, x.get() + textRenderer.getWidth(line.substring(0, cursorX - previousXIndex)) - 1, 25 + y, isAtEndOfLine()); drawCursor(matrices, x.get() + textRenderer.getWidth(line.substring(0, cursorX - previousXIndex)) - 1, 25 + y, isAtEndOfLine());
} }
this.textRenderer.draw(matrices, line, x.get(), 25 + y, token.color); this.textRenderer.draw(matrices, line, x.get(), 25 + y, token.color);
x.addAndGet(textRenderer.getWidth(line)); x.addAndGet(textRenderer.getWidth(line));
if (x.get() > this.width - 50 - lineNumberLength - 5) { if (x.get() > this.width - 50 - lineNumberLength - 5) {
@ -206,35 +252,85 @@ public class ScriptEditScreen extends Screen {
} }
private void key(int keyCode) { private void key(int keyCode) {
if (Screen.isSelectAll(keyCode)) {
this.cursorX = 0;
this.cursorY = 0;
this.savedCursorX = lines.get(lines.size() - 1).length();
this.savedCursorY = lines.size() - 1;
return;
} else if (Screen.isCopy(keyCode)) {
String copied = selection(false);
if (copied != null) {
setClipboard(copied);
}
return;
} else if (Screen.isPaste(keyCode)) {
String copied = getClipboard();
if (copied != null) {
insert(copied);
}
return;
} else if (Screen.isCut(keyCode)) {
String copied = selection(true);
if (copied != null) {
setClipboard(copied);
}
return;
}
SelectionManager.SelectionType selectionType = Screen.hasControlDown() ? SelectionManager.SelectionType.WORD : SelectionManager.SelectionType.CHARACTER;
boolean valid = true;
int previousCursorX = cursorX;
int previousCursorY = cursorY;
switch (keyCode) { switch (keyCode) {
case 257: case 257:
case 335: case 335:
selection(true);
newLine(); newLine();
valid = false;
break; break;
case 259: case 259:
backspace(); if (selection(true) == null) backspace(selectionType);
valid = false;
break; break;
case 261: case 261:
delete(); if (selection(true) == null) delete(selectionType);
valid = false;
break; break;
case 262: case 262:
moveCursor(1); moveCursor(1, selectionType);
valid = Screen.hasShiftDown();
break; break;
case 263: case 263:
moveCursor(-1); moveCursor(-1, selectionType);
valid = Screen.hasShiftDown();
break; break;
case 264: case 264:
moveDown(); moveDown();
valid = Screen.hasShiftDown();
break; break;
case 265: case 265:
moveUp(); moveUp();
valid = Screen.hasShiftDown();
break; break;
case 268: case 268:
cursorX = 0; cursorX = 0;
valid = Screen.hasShiftDown();
break; break;
case 269: case 269:
cursorX = lines.get(cursorY).length(); cursorX = lines.get(cursorY).length();
valid = Screen.hasShiftDown();
break; break;
default:
break;
}
if (valid) {
if (Screen.hasShiftDown() && savedCursorX == -1 && savedCursorY == -1) {
savedCursorX = previousCursorX;
savedCursorY = previousCursorY;
}
} else {
savedCursorY = -1;
savedCursorX = -1;
} }
} }
@ -260,21 +356,78 @@ public class ScriptEditScreen extends Screen {
if (super.charTyped(chr, modifiers)) { if (super.charTyped(chr, modifiers)) {
return true; return true;
} }
if (insert(chr, modifiers)) { selection(true);
return true; boolean valid = insert(chr + "");
} savedCursorY = -1;
return true; savedCursorX = -1;
return valid;
} }
private boolean insert(char chr, int modifiers) { private String selection(boolean remove) {
String line = lines.get(cursorY); if (savedCursorX == -1 || savedCursorY == -1) {
if (cursorX == line.length()) { return null;
line += chr; }
} else { int minSelectionY = Math.min(savedCursorY, cursorY);
line = line.substring(0, cursorX) + chr + line.substring(cursorX); int maxSelectionY = Math.max(savedCursorY, cursorY);
int minSelectionX = minSelectionY == cursorY ? cursorX : savedCursorX;
int maxSelectionX = maxSelectionY == cursorY ? cursorX : savedCursorX;
StringBuilder builder = new StringBuilder();
for (int i = minSelectionY; i <= maxSelectionY; i++) {
String line = lines.get(i);
if (i == minSelectionY && i == maxSelectionY) {
builder.append(line, minSelectionX, maxSelectionX);
} else if (i == minSelectionY) {
builder.append(line, minSelectionX, line.length());
} else if (i == maxSelectionY) {
builder.append(line, 0, Math.min(maxSelectionX, line.length()));
} else {
builder.append(line);
}
if (i != maxSelectionY) {
builder.append("\n");
}
}
if (remove) {
for (int i = maxSelectionY; i >= minSelectionY; i--) {
String line = lines.get(i);
if (i == minSelectionY && i == maxSelectionY) {
lines.set(i, line.substring(0, minSelectionX) + line.substring(maxSelectionX));
} else if (i == minSelectionY) {
lines.set(i, line.substring(0, minSelectionX));
} else if (i == maxSelectionY) {
lines.set(i, line.substring(Math.min(maxSelectionX, line.length())));
} else {
lines.remove(i);
}
}
if (minSelectionY != maxSelectionY) {
lines.set(minSelectionY, lines.get(minSelectionY) + lines.get(minSelectionY + 1));
lines.remove(minSelectionY + 1);
}
cursorX = minSelectionX;
cursorY = minSelectionY;
savedCursorX = -1;
savedCursorY = -1;
}
return builder.toString();
}
private boolean insert(String s) {
String[] split = s.split("\n");
for (int i = 0; i < split.length; i++) {
String line = lines.get(cursorY);
if (cursorX == line.length()) {
line += split[i];
} else {
line = line.substring(0, cursorX) + split[i] + line.substring(cursorX);
}
lines.set(cursorY, line);
cursorX += split[i].length();
if (i != split.length - 1) {
newLine();
}
} }
lines.set(cursorY, line);
cursorX++;
return true; return true;
} }
@ -289,58 +442,80 @@ public class ScriptEditScreen extends Screen {
return true; return true;
} }
private boolean backspace() { private boolean backspace(SelectionManager.SelectionType selectionType) {
if (cursorX == 0) { if (cursorX == 0) {
if (cursorY == 0) { if (cursorY == 0) {
return true; return true;
} }
String line = lines.get(cursorY); String previousLine = lines.get(cursorY - 1);
String prevLine = lines.get(cursorY - 1); lines.set(cursorY - 1, lines.get(cursorY - 1) + lines.remove(cursorY));
lines.set(cursorY - 1, prevLine + line);
lines.remove(cursorY);
cursorY--; cursorY--;
cursorX = prevLine.length(); cursorX = previousLine.length();
} else { } else {
String line = lines.get(cursorY); String line = lines.get(cursorY);
line = line.substring(0, cursorX - 1) + line.substring(cursorX); int remove = selectionType == SelectionManager.SelectionType.CHARACTER ? 1 : getWordLength(line, cursorX, -1);
line = line.substring(0, cursorX - remove) + line.substring(cursorX);
lines.set(cursorY, line); lines.set(cursorY, line);
cursorX--; cursorX -= remove;
} }
return true; return true;
} }
private boolean delete() { private boolean delete(SelectionManager.SelectionType selectionType) {
String line = lines.get(cursorY); if (cursorX == lines.get(cursorY).length()) {
if (cursorX == line.length()) {
if (cursorY == lines.size() - 1) { if (cursorY == lines.size() - 1) {
return true; return true;
} }
String nextLine = lines.get(cursorY + 1); String nextLine = lines.get(cursorY + 1);
lines.set(cursorY, line + nextLine); lines.remove(cursorY);
lines.remove(cursorY + 1); lines.set(cursorY, lines.get(cursorY) + nextLine);
} else { } else {
line = line.substring(0, cursorX) + line.substring(cursorX + 1); String line = lines.get(cursorY);
int remove = selectionType == SelectionManager.SelectionType.CHARACTER ? 1 : getWordLength(line, cursorX, 1);
line = line.substring(0, cursorX) + line.substring(cursorX + remove);
lines.set(cursorY, line); lines.set(cursorY, line);
} }
return true; return true;
} }
private boolean moveCursor(int offset) { private int getWordLength(String line, int cursorX, int direction) {
int i = cursorX;
while (i >= 0 && i < line.length()) {
char c = line.charAt(i);
if (Character.isLetterOrDigit(c)) {
i += direction;
} else {
break;
}
}
return Math.abs(i - cursorX);
}
private boolean moveCursor(int offset, SelectionManager.SelectionType selectionType) {
if (offset == 0) {
return true;
}
String line = lines.get(cursorY); String line = lines.get(cursorY);
if (cursorX + offset < 0) { if (offset > 0) {
if (cursorY == 0) { if (cursorX == line.length()) {
return true; if (cursorY == lines.size() - 1) {
return true;
}
cursorY++;
cursorX = 0;
} else {
cursorX += selectionType == SelectionManager.SelectionType.CHARACTER ? 1 : getWordLength(line, cursorX, 1);
} }
cursorY--;
cursorX = lines.get(cursorY).length();
} else if (cursorX + offset > line.length()) {
if (cursorY == lines.size() - 1) {
return true;
}
cursorY++;
cursorX = 0;
} else { } else {
cursorX += offset; if (cursorX == 0) {
if (cursorY == 0) {
return true;
}
cursorY--;
cursorX = lines.get(cursorY).length();
} else {
cursorX -= selectionType == SelectionManager.SelectionType.CHARACTER ? 1 : getWordLength(line, cursorX, -1);
}
} }
return true; return true;
} }