223 lines
8.5 KiB
Java
223 lines
8.5 KiB
Java
|
package net.minecraft.client.gui.screens.inventory;
|
||
|
|
||
|
import com.mojang.blaze3d.platform.Lighting;
|
||
|
import java.util.stream.IntStream;
|
||
|
import javax.annotation.Nullable;
|
||
|
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.multiplayer.ClientPacketListener;
|
||
|
import net.minecraft.client.renderer.RenderType;
|
||
|
import net.minecraft.client.renderer.blockentity.AbstractSignRenderer;
|
||
|
import net.minecraft.network.chat.CommonComponents;
|
||
|
import net.minecraft.network.chat.Component;
|
||
|
import net.minecraft.network.protocol.game.ServerboundSignUpdatePacket;
|
||
|
import net.minecraft.util.ARGB;
|
||
|
import net.minecraft.world.level.block.SignBlock;
|
||
|
import net.minecraft.world.level.block.entity.SignBlockEntity;
|
||
|
import net.minecraft.world.level.block.entity.SignText;
|
||
|
import net.minecraft.world.level.block.state.BlockState;
|
||
|
import net.minecraft.world.level.block.state.properties.WoodType;
|
||
|
import net.minecraftforge.api.distmarker.Dist;
|
||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||
|
import org.joml.Vector3f;
|
||
|
|
||
|
@OnlyIn(Dist.CLIENT)
|
||
|
public abstract class AbstractSignEditScreen extends Screen {
|
||
|
protected final SignBlockEntity sign;
|
||
|
private SignText text;
|
||
|
private final String[] messages;
|
||
|
private final boolean isFrontText;
|
||
|
protected final WoodType woodType;
|
||
|
private int frame;
|
||
|
private int line;
|
||
|
@Nullable
|
||
|
private TextFieldHelper signField;
|
||
|
|
||
|
public AbstractSignEditScreen(SignBlockEntity p_277842_, boolean p_277719_, boolean p_277969_) {
|
||
|
this(p_277842_, p_277719_, p_277969_, Component.translatable("sign.edit"));
|
||
|
}
|
||
|
|
||
|
public AbstractSignEditScreen(SignBlockEntity p_277792_, boolean p_277607_, boolean p_278039_, Component p_277393_) {
|
||
|
super(p_277393_);
|
||
|
this.sign = p_277792_;
|
||
|
this.text = p_277792_.getText(p_277607_);
|
||
|
this.isFrontText = p_277607_;
|
||
|
this.woodType = SignBlock.getWoodType(p_277792_.getBlockState().getBlock());
|
||
|
this.messages = IntStream.range(0, 4)
|
||
|
.mapToObj(p_277214_ -> this.text.getMessage(p_277214_, p_278039_))
|
||
|
.map(Component::getString)
|
||
|
.toArray(String[]::new);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected void init() {
|
||
|
this.addRenderableWidget(
|
||
|
Button.builder(CommonComponents.GUI_DONE, p_251194_ -> this.onDone())
|
||
|
.bounds(this.width / 2 - 100, this.height / 4 + 144, 200, 20)
|
||
|
.build()
|
||
|
);
|
||
|
this.signField = new TextFieldHelper(
|
||
|
() -> this.messages[this.line],
|
||
|
this::setMessage,
|
||
|
TextFieldHelper.createClipboardGetter(this.minecraft),
|
||
|
TextFieldHelper.createClipboardSetter(this.minecraft),
|
||
|
p_280850_ -> this.minecraft.font.width(p_280850_) <= this.sign.getMaxTextLineWidth()
|
||
|
);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void tick() {
|
||
|
this.frame++;
|
||
|
if (!this.isValid()) {
|
||
|
this.onDone();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private boolean isValid() {
|
||
|
return this.minecraft != null
|
||
|
&& this.minecraft.player != null
|
||
|
&& !this.sign.isRemoved()
|
||
|
&& !this.sign.playerIsTooFarAwayToEdit(this.minecraft.player.getUUID());
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean keyPressed(int p_252300_, int p_250424_, int p_250697_) {
|
||
|
if (p_252300_ == 265) {
|
||
|
this.line = this.line - 1 & 3;
|
||
|
this.signField.setCursorToEnd();
|
||
|
return true;
|
||
|
} else if (p_252300_ == 264 || p_252300_ == 257 || p_252300_ == 335) {
|
||
|
this.line = this.line + 1 & 3;
|
||
|
this.signField.setCursorToEnd();
|
||
|
return true;
|
||
|
} else {
|
||
|
return this.signField.keyPressed(p_252300_) ? true : super.keyPressed(p_252300_, p_250424_, p_250697_);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean charTyped(char p_252008_, int p_251178_) {
|
||
|
this.signField.charTyped(p_252008_);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void render(GuiGraphics p_282418_, int p_281700_, int p_283040_, float p_282799_) {
|
||
|
super.render(p_282418_, p_281700_, p_283040_, p_282799_);
|
||
|
p_282418_.flush();
|
||
|
Lighting.setupForFlatItems();
|
||
|
p_282418_.drawCenteredString(this.font, this.title, this.width / 2, 40, 16777215);
|
||
|
this.renderSign(p_282418_);
|
||
|
p_282418_.flush();
|
||
|
Lighting.setupFor3DItems();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void renderBackground(GuiGraphics p_334358_, int p_335184_, int p_333439_, float p_335736_) {
|
||
|
this.renderTransparentBackground(p_334358_);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onClose() {
|
||
|
this.onDone();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void removed() {
|
||
|
ClientPacketListener clientpacketlistener = this.minecraft.getConnection();
|
||
|
if (clientpacketlistener != null) {
|
||
|
clientpacketlistener.send(
|
||
|
new ServerboundSignUpdatePacket(
|
||
|
this.sign.getBlockPos(), this.isFrontText, this.messages[0], this.messages[1], this.messages[2], this.messages[3]
|
||
|
)
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean isPauseScreen() {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
protected abstract void renderSignBackground(GuiGraphics p_281459_);
|
||
|
|
||
|
protected abstract Vector3f getSignTextScale();
|
||
|
|
||
|
protected void offsetSign(GuiGraphics p_282672_, BlockState p_283056_) {
|
||
|
p_282672_.pose().translate(this.width / 2.0F, 90.0F, 50.0F);
|
||
|
}
|
||
|
|
||
|
private void renderSign(GuiGraphics p_282006_) {
|
||
|
p_282006_.pose().pushPose();
|
||
|
this.offsetSign(p_282006_, this.sign.getBlockState());
|
||
|
p_282006_.pose().pushPose();
|
||
|
this.renderSignBackground(p_282006_);
|
||
|
p_282006_.pose().popPose();
|
||
|
this.renderSignText(p_282006_);
|
||
|
p_282006_.pose().popPose();
|
||
|
}
|
||
|
|
||
|
private void renderSignText(GuiGraphics p_282366_) {
|
||
|
p_282366_.pose().translate(0.0F, 0.0F, 4.0F);
|
||
|
Vector3f vector3f = this.getSignTextScale();
|
||
|
p_282366_.pose().scale(vector3f.x(), vector3f.y(), vector3f.z());
|
||
|
int i = this.text.hasGlowingText() ? this.text.getColor().getTextColor() : AbstractSignRenderer.getDarkColor(this.text);
|
||
|
boolean flag = this.frame / 6 % 2 == 0;
|
||
|
int j = this.signField.getCursorPos();
|
||
|
int k = this.signField.getSelectionPos();
|
||
|
int l = 4 * this.sign.getTextLineHeight() / 2;
|
||
|
int i1 = this.line * this.sign.getTextLineHeight() - l;
|
||
|
|
||
|
for (int j1 = 0; j1 < this.messages.length; j1++) {
|
||
|
String s = this.messages[j1];
|
||
|
if (s != null) {
|
||
|
if (this.font.isBidirectional()) {
|
||
|
s = this.font.bidirectionalShaping(s);
|
||
|
}
|
||
|
|
||
|
int k1 = -this.font.width(s) / 2;
|
||
|
p_282366_.drawString(this.font, s, k1, j1 * this.sign.getTextLineHeight() - l, i, false);
|
||
|
if (j1 == this.line && j >= 0 && flag) {
|
||
|
int l1 = this.font.width(s.substring(0, Math.max(Math.min(j, s.length()), 0)));
|
||
|
int i2 = l1 - this.font.width(s) / 2;
|
||
|
if (j >= s.length()) {
|
||
|
p_282366_.drawString(this.font, "_", i2, i1, i, false);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (int k3 = 0; k3 < this.messages.length; k3++) {
|
||
|
String s1 = this.messages[k3];
|
||
|
if (s1 != null && k3 == this.line && j >= 0) {
|
||
|
int l3 = this.font.width(s1.substring(0, Math.max(Math.min(j, s1.length()), 0)));
|
||
|
int i4 = l3 - this.font.width(s1) / 2;
|
||
|
if (flag && j < s1.length()) {
|
||
|
p_282366_.fill(i4, i1 - 1, i4 + 1, i1 + this.sign.getTextLineHeight(), ARGB.opaque(i));
|
||
|
}
|
||
|
|
||
|
if (k != j) {
|
||
|
int j4 = Math.min(j, k);
|
||
|
int j2 = Math.max(j, k);
|
||
|
int k2 = this.font.width(s1.substring(0, j4)) - this.font.width(s1) / 2;
|
||
|
int l2 = this.font.width(s1.substring(0, j2)) - this.font.width(s1) / 2;
|
||
|
int i3 = Math.min(k2, l2);
|
||
|
int j3 = Math.max(k2, l2);
|
||
|
p_282366_.fill(RenderType.guiTextHighlight(), i3, i1, j3, i1 + this.sign.getTextLineHeight(), -16776961);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void setMessage(String p_277913_) {
|
||
|
this.messages[this.line] = p_277913_;
|
||
|
this.text = this.text.setMessage(this.line, Component.literal(p_277913_));
|
||
|
this.sign.setText(this.text, this.isFrontText);
|
||
|
}
|
||
|
|
||
|
private void onDone() {
|
||
|
this.minecraft.setScreen(null);
|
||
|
}
|
||
|
}
|