Code/net/minecraft/client/gui/screens/inventory/BookEditScreen.java

687 lines
28 KiB
Java

package net.minecraft.client.gui.screens.inventory;
import com.google.common.collect.Lists;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
import java.util.Optional;
import javax.annotation.Nullable;
import net.minecraft.ChatFormatting;
import net.minecraft.Util;
import net.minecraft.client.GameNarrator;
import net.minecraft.client.Minecraft;
import net.minecraft.client.StringSplitter;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.font.TextFieldHelper;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.renderer.Rect2i;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.Style;
import net.minecraft.network.protocol.game.ServerboundEditBookPacket;
import net.minecraft.server.network.Filterable;
import net.minecraft.util.FormattedCharSequence;
import net.minecraft.util.StringUtil;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.component.WritableBookContent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.commons.lang3.mutable.MutableInt;
@OnlyIn(Dist.CLIENT)
public class BookEditScreen extends Screen {
private static final int TEXT_WIDTH = 114;
private static final int TEXT_HEIGHT = 128;
private static final int IMAGE_WIDTH = 192;
private static final int IMAGE_HEIGHT = 192;
private static final int BACKGROUND_TEXTURE_WIDTH = 256;
private static final int BACKGROUND_TEXTURE_HEIGHT = 256;
private static final Component EDIT_TITLE_LABEL = Component.translatable("book.editTitle");
private static final Component FINALIZE_WARNING_LABEL = Component.translatable("book.finalizeWarning");
private static final FormattedCharSequence BLACK_CURSOR = FormattedCharSequence.forward("_", Style.EMPTY.withColor(ChatFormatting.BLACK));
private static final FormattedCharSequence GRAY_CURSOR = FormattedCharSequence.forward("_", Style.EMPTY.withColor(ChatFormatting.GRAY));
private final Player owner;
private final ItemStack book;
private boolean isModified;
private boolean isSigning;
private int frameTick;
private int currentPage;
private final List<String> pages = Lists.newArrayList();
private String title = "";
private final TextFieldHelper pageEdit = new TextFieldHelper(
this::getCurrentPageText, this::setCurrentPageText, this::getClipboard, this::setClipboard, p_280853_ -> p_280853_.length() < 1024 && this.font.wordWrapHeight(p_280853_, 114) <= 128
);
private final TextFieldHelper titleEdit = new TextFieldHelper(
() -> this.title, p_98175_ -> this.title = p_98175_, this::getClipboard, this::setClipboard, p_98170_ -> p_98170_.length() < 16
);
private long lastClickTime;
private int lastIndex = -1;
private PageButton forwardButton;
private PageButton backButton;
private Button doneButton;
private Button signButton;
private Button finalizeButton;
private Button cancelButton;
private final InteractionHand hand;
@Nullable
private BookEditScreen.DisplayCache displayCache = BookEditScreen.DisplayCache.EMPTY;
private Component pageMsg = CommonComponents.EMPTY;
private final Component ownerText;
public BookEditScreen(Player p_98076_, ItemStack p_98077_, InteractionHand p_98078_, WritableBookContent p_363680_) {
super(GameNarrator.NO_TITLE);
this.owner = p_98076_;
this.book = p_98077_;
this.hand = p_98078_;
p_363680_.getPages(Minecraft.getInstance().isTextFilteringEnabled()).forEach(this.pages::add);
if (this.pages.isEmpty()) {
this.pages.add("");
}
this.ownerText = Component.translatable("book.byAuthor", p_98076_.getName()).withStyle(ChatFormatting.DARK_GRAY);
}
private void setClipboard(String p_98148_) {
if (this.minecraft != null) {
TextFieldHelper.setClipboardContents(this.minecraft, p_98148_);
}
}
private String getClipboard() {
return this.minecraft != null ? TextFieldHelper.getClipboardContents(this.minecraft) : "";
}
private int getNumPages() {
return this.pages.size();
}
@Override
public void tick() {
super.tick();
this.frameTick++;
}
@Override
protected void init() {
this.clearDisplayCache();
this.signButton = this.addRenderableWidget(Button.builder(Component.translatable("book.signButton"), p_98177_ -> {
this.isSigning = true;
this.updateButtonVisibility();
}).bounds(this.width / 2 - 100, 196, 98, 20).build());
this.doneButton = this.addRenderableWidget(Button.builder(CommonComponents.GUI_DONE, p_280851_ -> {
this.minecraft.setScreen(null);
this.saveChanges(false);
}).bounds(this.width / 2 + 2, 196, 98, 20).build());
this.finalizeButton = this.addRenderableWidget(Button.builder(Component.translatable("book.finalizeButton"), p_280852_ -> {
if (this.isSigning) {
this.saveChanges(true);
this.minecraft.setScreen(null);
}
}).bounds(this.width / 2 - 100, 196, 98, 20).build());
this.cancelButton = this.addRenderableWidget(Button.builder(CommonComponents.GUI_CANCEL, p_98157_ -> {
if (this.isSigning) {
this.isSigning = false;
}
this.updateButtonVisibility();
}).bounds(this.width / 2 + 2, 196, 98, 20).build());
int i = (this.width - 192) / 2;
int j = 2;
this.forwardButton = this.addRenderableWidget(new PageButton(i + 116, 159, true, p_98144_ -> this.pageForward(), true));
this.backButton = this.addRenderableWidget(new PageButton(i + 43, 159, false, p_98113_ -> this.pageBack(), true));
this.updateButtonVisibility();
}
private void pageBack() {
if (this.currentPage > 0) {
this.currentPage--;
}
this.updateButtonVisibility();
this.clearDisplayCacheAfterPageChange();
}
private void pageForward() {
if (this.currentPage < this.getNumPages() - 1) {
this.currentPage++;
} else {
this.appendPageToBook();
if (this.currentPage < this.getNumPages() - 1) {
this.currentPage++;
}
}
this.updateButtonVisibility();
this.clearDisplayCacheAfterPageChange();
}
private void updateButtonVisibility() {
this.backButton.visible = !this.isSigning && this.currentPage > 0;
this.forwardButton.visible = !this.isSigning;
this.doneButton.visible = !this.isSigning;
this.signButton.visible = !this.isSigning;
this.cancelButton.visible = this.isSigning;
this.finalizeButton.visible = this.isSigning;
this.finalizeButton.active = !StringUtil.isBlank(this.title);
}
private void eraseEmptyTrailingPages() {
ListIterator<String> listiterator = this.pages.listIterator(this.pages.size());
while (listiterator.hasPrevious() && listiterator.previous().isEmpty()) {
listiterator.remove();
}
}
private void saveChanges(boolean p_98161_) {
if (this.isModified) {
this.eraseEmptyTrailingPages();
this.updateLocalCopy();
int i = this.hand == InteractionHand.MAIN_HAND ? this.owner.getInventory().getSelectedSlot() : 40;
this.minecraft
.getConnection()
.send(new ServerboundEditBookPacket(i, this.pages, p_98161_ ? Optional.of(this.title.trim()) : Optional.empty()));
}
}
private void updateLocalCopy() {
this.book.set(DataComponents.WRITABLE_BOOK_CONTENT, new WritableBookContent(this.pages.stream().map(Filterable::passThrough).toList()));
}
private void appendPageToBook() {
if (this.getNumPages() < 100) {
this.pages.add("");
this.isModified = true;
}
}
@Override
public boolean keyPressed(int p_98100_, int p_98101_, int p_98102_) {
if (super.keyPressed(p_98100_, p_98101_, p_98102_)) {
return true;
} else if (this.isSigning) {
return this.titleKeyPressed(p_98100_, p_98101_, p_98102_);
} else {
boolean flag = this.bookKeyPressed(p_98100_, p_98101_, p_98102_);
if (flag) {
this.clearDisplayCache();
return true;
} else {
return false;
}
}
}
@Override
public boolean charTyped(char p_98085_, int p_98086_) {
if (super.charTyped(p_98085_, p_98086_)) {
return true;
} else if (this.isSigning) {
boolean flag = this.titleEdit.charTyped(p_98085_);
if (flag) {
this.updateButtonVisibility();
this.isModified = true;
return true;
} else {
return false;
}
} else if (StringUtil.isAllowedChatCharacter(p_98085_)) {
this.pageEdit.insertText(Character.toString(p_98085_));
this.clearDisplayCache();
return true;
} else {
return false;
}
}
private boolean bookKeyPressed(int p_98153_, int p_98154_, int p_98155_) {
if (Screen.isSelectAll(p_98153_)) {
this.pageEdit.selectAll();
return true;
} else if (Screen.isCopy(p_98153_)) {
this.pageEdit.copy();
return true;
} else if (Screen.isPaste(p_98153_)) {
this.pageEdit.paste();
return true;
} else if (Screen.isCut(p_98153_)) {
this.pageEdit.cut();
return true;
} else {
TextFieldHelper.CursorStep textfieldhelper$cursorstep = Screen.hasControlDown() ? TextFieldHelper.CursorStep.WORD : TextFieldHelper.CursorStep.CHARACTER;
switch (p_98153_) {
case 257:
case 335:
this.pageEdit.insertText("\n");
return true;
case 259:
this.pageEdit.removeFromCursor(-1, textfieldhelper$cursorstep);
return true;
case 261:
this.pageEdit.removeFromCursor(1, textfieldhelper$cursorstep);
return true;
case 262:
this.pageEdit.moveBy(1, Screen.hasShiftDown(), textfieldhelper$cursorstep);
return true;
case 263:
this.pageEdit.moveBy(-1, Screen.hasShiftDown(), textfieldhelper$cursorstep);
return true;
case 264:
this.keyDown();
return true;
case 265:
this.keyUp();
return true;
case 266:
this.backButton.onPress();
return true;
case 267:
this.forwardButton.onPress();
return true;
case 268:
this.keyHome();
return true;
case 269:
this.keyEnd();
return true;
default:
return false;
}
}
}
private void keyUp() {
this.changeLine(-1);
}
private void keyDown() {
this.changeLine(1);
}
private void changeLine(int p_98098_) {
int i = this.pageEdit.getCursorPos();
int j = this.getDisplayCache().changeLine(i, p_98098_);
this.pageEdit.setCursorPos(j, Screen.hasShiftDown());
}
private void keyHome() {
if (Screen.hasControlDown()) {
this.pageEdit.setCursorToStart(Screen.hasShiftDown());
} else {
int i = this.pageEdit.getCursorPos();
int j = this.getDisplayCache().findLineStart(i);
this.pageEdit.setCursorPos(j, Screen.hasShiftDown());
}
}
private void keyEnd() {
if (Screen.hasControlDown()) {
this.pageEdit.setCursorToEnd(Screen.hasShiftDown());
} else {
BookEditScreen.DisplayCache bookeditscreen$displaycache = this.getDisplayCache();
int i = this.pageEdit.getCursorPos();
int j = bookeditscreen$displaycache.findLineEnd(i);
this.pageEdit.setCursorPos(j, Screen.hasShiftDown());
}
}
private boolean titleKeyPressed(int p_98164_, int p_98165_, int p_98166_) {
switch (p_98164_) {
case 257:
case 335:
if (!this.title.isEmpty()) {
this.saveChanges(true);
this.minecraft.setScreen(null);
}
return true;
case 259:
this.titleEdit.removeCharsFromCursor(-1);
this.updateButtonVisibility();
this.isModified = true;
return true;
default:
return false;
}
}
private String getCurrentPageText() {
return this.currentPage >= 0 && this.currentPage < this.pages.size() ? this.pages.get(this.currentPage) : "";
}
private void setCurrentPageText(String p_98159_) {
if (this.currentPage >= 0 && this.currentPage < this.pages.size()) {
this.pages.set(this.currentPage, p_98159_);
this.isModified = true;
this.clearDisplayCache();
}
}
@Override
public void render(GuiGraphics p_281724_, int p_282965_, int p_283294_, float p_281293_) {
super.render(p_281724_, p_282965_, p_283294_, p_281293_);
this.setFocused(null);
int i = (this.width - 192) / 2;
int j = 2;
if (this.isSigning) {
boolean flag = this.frameTick / 6 % 2 == 0;
FormattedCharSequence formattedcharsequence = FormattedCharSequence.composite(
FormattedCharSequence.forward(this.title, Style.EMPTY), flag ? BLACK_CURSOR : GRAY_CURSOR
);
int k = this.font.width(EDIT_TITLE_LABEL);
p_281724_.drawString(this.font, EDIT_TITLE_LABEL, i + 36 + (114 - k) / 2, 34, 0, false);
int l = this.font.width(formattedcharsequence);
p_281724_.drawString(this.font, formattedcharsequence, i + 36 + (114 - l) / 2, 50, 0, false);
int i1 = this.font.width(this.ownerText);
p_281724_.drawString(this.font, this.ownerText, i + 36 + (114 - i1) / 2, 60, 0, false);
p_281724_.drawWordWrap(this.font, FINALIZE_WARNING_LABEL, i + 36, 82, 114, 0, false);
} else {
int j1 = this.font.width(this.pageMsg);
p_281724_.drawString(this.font, this.pageMsg, i - j1 + 192 - 44, 18, 0, false);
BookEditScreen.DisplayCache bookeditscreen$displaycache = this.getDisplayCache();
for (BookEditScreen.LineInfo bookeditscreen$lineinfo : bookeditscreen$displaycache.lines) {
p_281724_.drawString(
this.font, bookeditscreen$lineinfo.asComponent, bookeditscreen$lineinfo.x, bookeditscreen$lineinfo.y, -16777216, false
);
}
this.renderHighlight(p_281724_, bookeditscreen$displaycache.selection);
this.renderCursor(p_281724_, bookeditscreen$displaycache.cursor, bookeditscreen$displaycache.cursorAtEnd);
}
}
@Override
public void renderBackground(GuiGraphics p_298379_, int p_298216_, int p_301014_, float p_300512_) {
this.renderTransparentBackground(p_298379_);
p_298379_.blit(RenderType::guiTextured, BookViewScreen.BOOK_LOCATION, (this.width - 192) / 2, 2, 0.0F, 0.0F, 192, 192, 256, 256);
}
private void renderCursor(GuiGraphics p_281833_, BookEditScreen.Pos2i p_282190_, boolean p_282412_) {
if (this.frameTick / 6 % 2 == 0) {
p_282190_ = this.convertLocalToScreen(p_282190_);
if (!p_282412_) {
p_281833_.fill(p_282190_.x, p_282190_.y - 1, p_282190_.x + 1, p_282190_.y + 9, -16777216);
} else {
p_281833_.drawString(this.font, "_", p_282190_.x, p_282190_.y, 0, false);
}
}
}
private void renderHighlight(GuiGraphics p_282188_, Rect2i[] p_265482_) {
for (Rect2i rect2i : p_265482_) {
int i = rect2i.getX();
int j = rect2i.getY();
int k = i + rect2i.getWidth();
int l = j + rect2i.getHeight();
p_282188_.fill(RenderType.guiTextHighlight(), i, j, k, l, -16776961);
}
}
private BookEditScreen.Pos2i convertScreenToLocal(BookEditScreen.Pos2i p_98115_) {
return new BookEditScreen.Pos2i(p_98115_.x - (this.width - 192) / 2 - 36, p_98115_.y - 32);
}
private BookEditScreen.Pos2i convertLocalToScreen(BookEditScreen.Pos2i p_98146_) {
return new BookEditScreen.Pos2i(p_98146_.x + (this.width - 192) / 2 + 36, p_98146_.y + 32);
}
@Override
public boolean mouseClicked(double p_98088_, double p_98089_, int p_98090_) {
if (super.mouseClicked(p_98088_, p_98089_, p_98090_)) {
return true;
} else {
if (p_98090_ == 0) {
long i = Util.getMillis();
BookEditScreen.DisplayCache bookeditscreen$displaycache = this.getDisplayCache();
int j = bookeditscreen$displaycache.getIndexAtPosition(this.font, this.convertScreenToLocal(new BookEditScreen.Pos2i((int)p_98088_, (int)p_98089_)));
if (j >= 0) {
if (j != this.lastIndex || i - this.lastClickTime >= 250L) {
this.pageEdit.setCursorPos(j, Screen.hasShiftDown());
} else if (!this.pageEdit.isSelecting()) {
this.selectWord(j);
} else {
this.pageEdit.selectAll();
}
this.clearDisplayCache();
}
this.lastIndex = j;
this.lastClickTime = i;
}
return true;
}
}
private void selectWord(int p_98142_) {
String s = this.getCurrentPageText();
this.pageEdit.setSelectionRange(StringSplitter.getWordPosition(s, -1, p_98142_, false), StringSplitter.getWordPosition(s, 1, p_98142_, false));
}
@Override
public boolean mouseDragged(double p_98092_, double p_98093_, int p_98094_, double p_98095_, double p_98096_) {
if (super.mouseDragged(p_98092_, p_98093_, p_98094_, p_98095_, p_98096_)) {
return true;
} else {
if (p_98094_ == 0) {
BookEditScreen.DisplayCache bookeditscreen$displaycache = this.getDisplayCache();
int i = bookeditscreen$displaycache.getIndexAtPosition(this.font, this.convertScreenToLocal(new BookEditScreen.Pos2i((int)p_98092_, (int)p_98093_)));
this.pageEdit.setCursorPos(i, true);
this.clearDisplayCache();
}
return true;
}
}
private BookEditScreen.DisplayCache getDisplayCache() {
if (this.displayCache == null) {
this.displayCache = this.rebuildDisplayCache();
this.pageMsg = Component.translatable("book.pageIndicator", this.currentPage + 1, this.getNumPages());
}
return this.displayCache;
}
private void clearDisplayCache() {
this.displayCache = null;
}
private void clearDisplayCacheAfterPageChange() {
this.pageEdit.setCursorToEnd();
this.clearDisplayCache();
}
private BookEditScreen.DisplayCache rebuildDisplayCache() {
String s = this.getCurrentPageText();
if (s.isEmpty()) {
return BookEditScreen.DisplayCache.EMPTY;
} else {
int i = this.pageEdit.getCursorPos();
int j = this.pageEdit.getSelectionPos();
IntList intlist = new IntArrayList();
List<BookEditScreen.LineInfo> list = Lists.newArrayList();
MutableInt mutableint = new MutableInt();
MutableBoolean mutableboolean = new MutableBoolean();
StringSplitter stringsplitter = this.font.getSplitter();
stringsplitter.splitLines(s, 114, Style.EMPTY, true, (p_98132_, p_98133_, p_98134_) -> {
int k3 = mutableint.getAndIncrement();
String s2 = s.substring(p_98133_, p_98134_);
mutableboolean.setValue(s2.endsWith("\n"));
String s3 = StringUtils.stripEnd(s2, " \n");
int l3 = k3 * 9;
BookEditScreen.Pos2i bookeditscreen$pos2i1 = this.convertLocalToScreen(new BookEditScreen.Pos2i(0, l3));
intlist.add(p_98133_);
list.add(new BookEditScreen.LineInfo(p_98132_, s3, bookeditscreen$pos2i1.x, bookeditscreen$pos2i1.y));
});
int[] aint = intlist.toIntArray();
boolean flag = i == s.length();
BookEditScreen.Pos2i bookeditscreen$pos2i;
if (flag && mutableboolean.isTrue()) {
bookeditscreen$pos2i = new BookEditScreen.Pos2i(0, list.size() * 9);
} else {
int k = findLineFromPos(aint, i);
int l = this.font.width(s.substring(aint[k], i));
bookeditscreen$pos2i = new BookEditScreen.Pos2i(l, k * 9);
}
List<Rect2i> list1 = Lists.newArrayList();
if (i != j) {
int l2 = Math.min(i, j);
int i1 = Math.max(i, j);
int j1 = findLineFromPos(aint, l2);
int k1 = findLineFromPos(aint, i1);
if (j1 == k1) {
int l1 = j1 * 9;
int i2 = aint[j1];
list1.add(this.createPartialLineSelection(s, stringsplitter, l2, i1, l1, i2));
} else {
int i3 = j1 + 1 > aint.length ? s.length() : aint[j1 + 1];
list1.add(this.createPartialLineSelection(s, stringsplitter, l2, i3, j1 * 9, aint[j1]));
for (int j3 = j1 + 1; j3 < k1; j3++) {
int j2 = j3 * 9;
String s1 = s.substring(aint[j3], aint[j3 + 1]);
int k2 = (int)stringsplitter.stringWidth(s1);
list1.add(this.createSelection(new BookEditScreen.Pos2i(0, j2), new BookEditScreen.Pos2i(k2, j2 + 9)));
}
list1.add(this.createPartialLineSelection(s, stringsplitter, aint[k1], i1, k1 * 9, aint[k1]));
}
}
return new BookEditScreen.DisplayCache(
s, bookeditscreen$pos2i, flag, aint, list.toArray(new BookEditScreen.LineInfo[0]), list1.toArray(new Rect2i[0])
);
}
}
static int findLineFromPos(int[] p_98150_, int p_98151_) {
int i = Arrays.binarySearch(p_98150_, p_98151_);
return i < 0 ? -(i + 2) : i;
}
private Rect2i createPartialLineSelection(String p_98120_, StringSplitter p_98121_, int p_98122_, int p_98123_, int p_98124_, int p_98125_) {
String s = p_98120_.substring(p_98125_, p_98122_);
String s1 = p_98120_.substring(p_98125_, p_98123_);
BookEditScreen.Pos2i bookeditscreen$pos2i = new BookEditScreen.Pos2i((int)p_98121_.stringWidth(s), p_98124_);
BookEditScreen.Pos2i bookeditscreen$pos2i1 = new BookEditScreen.Pos2i((int)p_98121_.stringWidth(s1), p_98124_ + 9);
return this.createSelection(bookeditscreen$pos2i, bookeditscreen$pos2i1);
}
private Rect2i createSelection(BookEditScreen.Pos2i p_98117_, BookEditScreen.Pos2i p_98118_) {
BookEditScreen.Pos2i bookeditscreen$pos2i = this.convertLocalToScreen(p_98117_);
BookEditScreen.Pos2i bookeditscreen$pos2i1 = this.convertLocalToScreen(p_98118_);
int i = Math.min(bookeditscreen$pos2i.x, bookeditscreen$pos2i1.x);
int j = Math.max(bookeditscreen$pos2i.x, bookeditscreen$pos2i1.x);
int k = Math.min(bookeditscreen$pos2i.y, bookeditscreen$pos2i1.y);
int l = Math.max(bookeditscreen$pos2i.y, bookeditscreen$pos2i1.y);
return new Rect2i(i, k, j - i, l - k);
}
@OnlyIn(Dist.CLIENT)
static class DisplayCache {
static final BookEditScreen.DisplayCache EMPTY = new BookEditScreen.DisplayCache(
"",
new BookEditScreen.Pos2i(0, 0),
true,
new int[]{0},
new BookEditScreen.LineInfo[]{new BookEditScreen.LineInfo(Style.EMPTY, "", 0, 0)},
new Rect2i[0]
);
private final String fullText;
final BookEditScreen.Pos2i cursor;
final boolean cursorAtEnd;
private final int[] lineStarts;
final BookEditScreen.LineInfo[] lines;
final Rect2i[] selection;
public DisplayCache(
String p_98201_, BookEditScreen.Pos2i p_98202_, boolean p_98203_, int[] p_98204_, BookEditScreen.LineInfo[] p_98205_, Rect2i[] p_98206_
) {
this.fullText = p_98201_;
this.cursor = p_98202_;
this.cursorAtEnd = p_98203_;
this.lineStarts = p_98204_;
this.lines = p_98205_;
this.selection = p_98206_;
}
public int getIndexAtPosition(Font p_98214_, BookEditScreen.Pos2i p_98215_) {
int i = p_98215_.y / 9;
if (i < 0) {
return 0;
} else if (i >= this.lines.length) {
return this.fullText.length();
} else {
BookEditScreen.LineInfo bookeditscreen$lineinfo = this.lines[i];
return this.lineStarts[i] + p_98214_.getSplitter().plainIndexAtWidth(bookeditscreen$lineinfo.contents, p_98215_.x, bookeditscreen$lineinfo.style);
}
}
public int changeLine(int p_98211_, int p_98212_) {
int i = BookEditScreen.findLineFromPos(this.lineStarts, p_98211_);
int j = i + p_98212_;
int k;
if (0 <= j && j < this.lineStarts.length) {
int l = p_98211_ - this.lineStarts[i];
int i1 = this.lines[j].contents.length();
k = this.lineStarts[j] + Math.min(l, i1);
} else {
k = p_98211_;
}
return k;
}
public int findLineStart(int p_98209_) {
int i = BookEditScreen.findLineFromPos(this.lineStarts, p_98209_);
return this.lineStarts[i];
}
public int findLineEnd(int p_98219_) {
int i = BookEditScreen.findLineFromPos(this.lineStarts, p_98219_);
return this.lineStarts[i] + this.lines[i].contents.length();
}
}
@OnlyIn(Dist.CLIENT)
static class LineInfo {
final Style style;
final String contents;
final Component asComponent;
final int x;
final int y;
public LineInfo(Style p_98232_, String p_98233_, int p_98234_, int p_98235_) {
this.style = p_98232_;
this.contents = p_98233_;
this.x = p_98234_;
this.y = p_98235_;
this.asComponent = Component.literal(p_98233_).setStyle(p_98232_);
}
}
@OnlyIn(Dist.CLIENT)
static class Pos2i {
public final int x;
public final int y;
Pos2i(int p_98249_, int p_98250_) {
this.x = p_98249_;
this.y = p_98250_;
}
}
}