264 lines
9.8 KiB
Java
264 lines
9.8 KiB
Java
|
package net.minecraft.client.gui.screens.inventory;
|
||
|
|
||
|
import java.util.Collections;
|
||
|
import java.util.List;
|
||
|
import javax.annotation.Nullable;
|
||
|
import net.minecraft.client.GameNarrator;
|
||
|
import net.minecraft.client.Minecraft;
|
||
|
import net.minecraft.client.gui.GuiGraphics;
|
||
|
import net.minecraft.client.gui.components.Button;
|
||
|
import net.minecraft.client.gui.screens.Screen;
|
||
|
import net.minecraft.client.renderer.RenderType;
|
||
|
import net.minecraft.core.component.DataComponents;
|
||
|
import net.minecraft.network.chat.ClickEvent;
|
||
|
import net.minecraft.network.chat.CommonComponents;
|
||
|
import net.minecraft.network.chat.Component;
|
||
|
import net.minecraft.network.chat.FormattedText;
|
||
|
import net.minecraft.network.chat.Style;
|
||
|
import net.minecraft.resources.ResourceLocation;
|
||
|
import net.minecraft.util.FormattedCharSequence;
|
||
|
import net.minecraft.util.Mth;
|
||
|
import net.minecraft.world.item.ItemStack;
|
||
|
import net.minecraft.world.item.component.WritableBookContent;
|
||
|
import net.minecraft.world.item.component.WrittenBookContent;
|
||
|
import net.minecraftforge.api.distmarker.Dist;
|
||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||
|
|
||
|
@OnlyIn(Dist.CLIENT)
|
||
|
public class BookViewScreen extends Screen {
|
||
|
public static final int PAGE_INDICATOR_TEXT_Y_OFFSET = 16;
|
||
|
public static final int PAGE_TEXT_X_OFFSET = 36;
|
||
|
public static final int PAGE_TEXT_Y_OFFSET = 30;
|
||
|
private static final int BACKGROUND_TEXTURE_WIDTH = 256;
|
||
|
private static final int BACKGROUND_TEXTURE_HEIGHT = 256;
|
||
|
public static final BookViewScreen.BookAccess EMPTY_ACCESS = new BookViewScreen.BookAccess(List.of());
|
||
|
public static final ResourceLocation BOOK_LOCATION = ResourceLocation.withDefaultNamespace("textures/gui/book.png");
|
||
|
protected static final int TEXT_WIDTH = 114;
|
||
|
protected static final int TEXT_HEIGHT = 128;
|
||
|
protected static final int IMAGE_WIDTH = 192;
|
||
|
protected static final int IMAGE_HEIGHT = 192;
|
||
|
private BookViewScreen.BookAccess bookAccess;
|
||
|
private int currentPage;
|
||
|
private List<FormattedCharSequence> cachedPageComponents = Collections.emptyList();
|
||
|
private int cachedPage = -1;
|
||
|
private Component pageMsg = CommonComponents.EMPTY;
|
||
|
private PageButton forwardButton;
|
||
|
private PageButton backButton;
|
||
|
private final boolean playTurnSound;
|
||
|
|
||
|
public BookViewScreen(BookViewScreen.BookAccess p_98264_) {
|
||
|
this(p_98264_, true);
|
||
|
}
|
||
|
|
||
|
public BookViewScreen() {
|
||
|
this(EMPTY_ACCESS, false);
|
||
|
}
|
||
|
|
||
|
private BookViewScreen(BookViewScreen.BookAccess p_98266_, boolean p_98267_) {
|
||
|
super(GameNarrator.NO_TITLE);
|
||
|
this.bookAccess = p_98266_;
|
||
|
this.playTurnSound = p_98267_;
|
||
|
}
|
||
|
|
||
|
public void setBookAccess(BookViewScreen.BookAccess p_98289_) {
|
||
|
this.bookAccess = p_98289_;
|
||
|
this.currentPage = Mth.clamp(this.currentPage, 0, p_98289_.getPageCount());
|
||
|
this.updateButtonVisibility();
|
||
|
this.cachedPage = -1;
|
||
|
}
|
||
|
|
||
|
public boolean setPage(int p_98276_) {
|
||
|
int i = Mth.clamp(p_98276_, 0, this.bookAccess.getPageCount() - 1);
|
||
|
if (i != this.currentPage) {
|
||
|
this.currentPage = i;
|
||
|
this.updateButtonVisibility();
|
||
|
this.cachedPage = -1;
|
||
|
return true;
|
||
|
} else {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected boolean forcePage(int p_98295_) {
|
||
|
return this.setPage(p_98295_);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected void init() {
|
||
|
this.createMenuControls();
|
||
|
this.createPageControlButtons();
|
||
|
}
|
||
|
|
||
|
protected void createMenuControls() {
|
||
|
this.addRenderableWidget(Button.builder(CommonComponents.GUI_DONE, p_389311_ -> this.onClose()).bounds(this.width / 2 - 100, 196, 200, 20).build());
|
||
|
}
|
||
|
|
||
|
protected void createPageControlButtons() {
|
||
|
int i = (this.width - 192) / 2;
|
||
|
int j = 2;
|
||
|
this.forwardButton = this.addRenderableWidget(new PageButton(i + 116, 159, true, p_98297_ -> this.pageForward(), this.playTurnSound));
|
||
|
this.backButton = this.addRenderableWidget(new PageButton(i + 43, 159, false, p_98287_ -> this.pageBack(), this.playTurnSound));
|
||
|
this.updateButtonVisibility();
|
||
|
}
|
||
|
|
||
|
private int getNumPages() {
|
||
|
return this.bookAccess.getPageCount();
|
||
|
}
|
||
|
|
||
|
protected void pageBack() {
|
||
|
if (this.currentPage > 0) {
|
||
|
this.currentPage--;
|
||
|
}
|
||
|
|
||
|
this.updateButtonVisibility();
|
||
|
}
|
||
|
|
||
|
protected void pageForward() {
|
||
|
if (this.currentPage < this.getNumPages() - 1) {
|
||
|
this.currentPage++;
|
||
|
}
|
||
|
|
||
|
this.updateButtonVisibility();
|
||
|
}
|
||
|
|
||
|
private void updateButtonVisibility() {
|
||
|
this.forwardButton.visible = this.currentPage < this.getNumPages() - 1;
|
||
|
this.backButton.visible = this.currentPage > 0;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean keyPressed(int p_98278_, int p_98279_, int p_98280_) {
|
||
|
if (super.keyPressed(p_98278_, p_98279_, p_98280_)) {
|
||
|
return true;
|
||
|
} else {
|
||
|
switch (p_98278_) {
|
||
|
case 266:
|
||
|
this.backButton.onPress();
|
||
|
return true;
|
||
|
case 267:
|
||
|
this.forwardButton.onPress();
|
||
|
return true;
|
||
|
default:
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void render(GuiGraphics p_281997_, int p_281262_, int p_283321_, float p_282251_) {
|
||
|
super.render(p_281997_, p_281262_, p_283321_, p_282251_);
|
||
|
int i = (this.width - 192) / 2;
|
||
|
int j = 2;
|
||
|
if (this.cachedPage != this.currentPage) {
|
||
|
FormattedText formattedtext = this.bookAccess.getPage(this.currentPage);
|
||
|
this.cachedPageComponents = this.font.split(formattedtext, 114);
|
||
|
this.pageMsg = Component.translatable("book.pageIndicator", this.currentPage + 1, Math.max(this.getNumPages(), 1));
|
||
|
}
|
||
|
|
||
|
this.cachedPage = this.currentPage;
|
||
|
int i1 = this.font.width(this.pageMsg);
|
||
|
p_281997_.drawString(this.font, this.pageMsg, i - i1 + 192 - 44, 18, 0, false);
|
||
|
int k = Math.min(128 / 9, this.cachedPageComponents.size());
|
||
|
|
||
|
for (int l = 0; l < k; l++) {
|
||
|
FormattedCharSequence formattedcharsequence = this.cachedPageComponents.get(l);
|
||
|
p_281997_.drawString(this.font, formattedcharsequence, i + 36, 32 + l * 9, 0, false);
|
||
|
}
|
||
|
|
||
|
Style style = this.getClickedComponentStyleAt(p_281262_, p_283321_);
|
||
|
if (style != null) {
|
||
|
p_281997_.renderComponentHoverEffect(this.font, style, p_281262_, p_283321_);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void renderBackground(GuiGraphics p_301081_, int p_297765_, int p_300192_, float p_297977_) {
|
||
|
this.renderTransparentBackground(p_301081_);
|
||
|
p_301081_.blit(RenderType::guiTextured, BOOK_LOCATION, (this.width - 192) / 2, 2, 0.0F, 0.0F, 192, 192, 256, 256);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean mouseClicked(double p_98272_, double p_98273_, int p_98274_) {
|
||
|
if (p_98274_ == 0) {
|
||
|
Style style = this.getClickedComponentStyleAt(p_98272_, p_98273_);
|
||
|
if (style != null && this.handleComponentClicked(style)) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return super.mouseClicked(p_98272_, p_98273_, p_98274_);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean handleComponentClicked(Style p_98293_) {
|
||
|
ClickEvent clickevent = p_98293_.getClickEvent();
|
||
|
if (clickevent == null) {
|
||
|
return false;
|
||
|
} else if (clickevent instanceof ClickEvent.ChangePage(int i)) {
|
||
|
return this.forcePage(i - 1);
|
||
|
} else {
|
||
|
boolean flag = super.handleComponentClicked(p_98293_);
|
||
|
if (flag && clickevent.action() == ClickEvent.Action.RUN_COMMAND) {
|
||
|
this.closeScreen();
|
||
|
}
|
||
|
|
||
|
return flag;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected void closeScreen() {
|
||
|
this.minecraft.setScreen(null);
|
||
|
}
|
||
|
|
||
|
@Nullable
|
||
|
public Style getClickedComponentStyleAt(double p_98269_, double p_98270_) {
|
||
|
if (this.cachedPageComponents.isEmpty()) {
|
||
|
return null;
|
||
|
} else {
|
||
|
int i = Mth.floor(p_98269_ - (this.width - 192) / 2 - 36.0);
|
||
|
int j = Mth.floor(p_98270_ - 2.0 - 30.0);
|
||
|
if (i >= 0 && j >= 0) {
|
||
|
int k = Math.min(128 / 9, this.cachedPageComponents.size());
|
||
|
if (i <= 114 && j < 9 * k + k) {
|
||
|
int l = j / 9;
|
||
|
if (l >= 0 && l < this.cachedPageComponents.size()) {
|
||
|
FormattedCharSequence formattedcharsequence = this.cachedPageComponents.get(l);
|
||
|
return this.minecraft.font.getSplitter().componentStyleAtWidth(formattedcharsequence, i);
|
||
|
} else {
|
||
|
return null;
|
||
|
}
|
||
|
} else {
|
||
|
return null;
|
||
|
}
|
||
|
} else {
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@OnlyIn(Dist.CLIENT)
|
||
|
public record BookAccess(List<Component> pages) {
|
||
|
public int getPageCount() {
|
||
|
return this.pages.size();
|
||
|
}
|
||
|
|
||
|
public FormattedText getPage(int p_98311_) {
|
||
|
return p_98311_ >= 0 && p_98311_ < this.getPageCount() ? this.pages.get(p_98311_) : FormattedText.EMPTY;
|
||
|
}
|
||
|
|
||
|
@Nullable
|
||
|
public static BookViewScreen.BookAccess fromItem(ItemStack p_98309_) {
|
||
|
boolean flag = Minecraft.getInstance().isTextFilteringEnabled();
|
||
|
WrittenBookContent writtenbookcontent = p_98309_.get(DataComponents.WRITTEN_BOOK_CONTENT);
|
||
|
if (writtenbookcontent != null) {
|
||
|
return new BookViewScreen.BookAccess(writtenbookcontent.getPages(flag));
|
||
|
} else {
|
||
|
WritableBookContent writablebookcontent = p_98309_.get(DataComponents.WRITABLE_BOOK_CONTENT);
|
||
|
return writablebookcontent != null
|
||
|
? new BookViewScreen.BookAccess(writablebookcontent.getPages(flag).<Component>map(Component::literal).toList())
|
||
|
: null;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|