256 lines
8.4 KiB
Java
256 lines
8.4 KiB
Java
package net.minecraft.client.gui.screens;
|
|
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.client.GuiMessageTag;
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.gui.GuiGraphics;
|
|
import net.minecraft.client.gui.components.ChatComponent;
|
|
import net.minecraft.client.gui.components.CommandSuggestions;
|
|
import net.minecraft.client.gui.components.EditBox;
|
|
import net.minecraft.client.gui.narration.NarratedElementType;
|
|
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.network.chat.MutableComponent;
|
|
import net.minecraft.network.chat.Style;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.util.StringUtil;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class ChatScreen extends Screen {
|
|
public static final double MOUSE_SCROLL_SPEED = 7.0;
|
|
private static final Component USAGE_TEXT = Component.translatable("chat_screen.usage");
|
|
private static final int TOOLTIP_MAX_WIDTH = 210;
|
|
private String historyBuffer = "";
|
|
/**
|
|
* keeps position of which chat message you will select when you press up, (does not increase for duplicated messages sent immediately after each other)
|
|
*/
|
|
private int historyPos = -1;
|
|
/**
|
|
* Chat entry field
|
|
*/
|
|
protected EditBox input;
|
|
/**
|
|
* is the text that appears when you press the chat key and the input box appears pre-filled
|
|
*/
|
|
private String initial;
|
|
CommandSuggestions commandSuggestions;
|
|
|
|
public ChatScreen(String initial) {
|
|
super(Component.translatable("chat_screen.title"));
|
|
this.initial = initial;
|
|
}
|
|
|
|
@Override
|
|
protected void init() {
|
|
this.historyPos = this.minecraft.gui.getChat().getRecentChat().size();
|
|
this.input = new EditBox(this.minecraft.fontFilterFishy, 4, this.height - 12, this.width - 4, 12, Component.translatable("chat.editBox")) {
|
|
@Override
|
|
protected MutableComponent createNarrationMessage() {
|
|
return super.createNarrationMessage().append(ChatScreen.this.commandSuggestions.getNarrationMessage());
|
|
}
|
|
};
|
|
this.input.setMaxLength(256);
|
|
this.input.setBordered(false);
|
|
this.input.setValue(this.initial);
|
|
this.input.setResponder(this::onEdited);
|
|
this.input.setCanLoseFocus(false);
|
|
this.addWidget(this.input);
|
|
this.commandSuggestions = new CommandSuggestions(this.minecraft, this, this.input, this.font, false, false, 1, 10, true, -805306368);
|
|
this.commandSuggestions.setAllowHiding(false);
|
|
this.commandSuggestions.updateCommandInfo();
|
|
}
|
|
|
|
@Override
|
|
protected void setInitialFocus() {
|
|
this.setInitialFocus(this.input);
|
|
}
|
|
|
|
@Override
|
|
public void resize(Minecraft minecraft, int width, int height) {
|
|
String string = this.input.getValue();
|
|
this.init(minecraft, width, height);
|
|
this.setChatLine(string);
|
|
this.commandSuggestions.updateCommandInfo();
|
|
}
|
|
|
|
@Override
|
|
public void removed() {
|
|
this.minecraft.gui.getChat().resetChatScroll();
|
|
}
|
|
|
|
private void onEdited(String value) {
|
|
String string = this.input.getValue();
|
|
this.commandSuggestions.setAllowSuggestions(!string.equals(this.initial));
|
|
this.commandSuggestions.updateCommandInfo();
|
|
}
|
|
|
|
@Override
|
|
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
|
if (this.commandSuggestions.keyPressed(keyCode, scanCode, modifiers)) {
|
|
return true;
|
|
} else if (super.keyPressed(keyCode, scanCode, modifiers)) {
|
|
return true;
|
|
} else if (keyCode == 256) {
|
|
this.minecraft.setScreen(null);
|
|
return true;
|
|
} else if (keyCode == 257 || keyCode == 335) {
|
|
this.handleChatInput(this.input.getValue(), true);
|
|
this.minecraft.setScreen(null);
|
|
return true;
|
|
} else if (keyCode == 265) {
|
|
this.moveInHistory(-1);
|
|
return true;
|
|
} else if (keyCode == 264) {
|
|
this.moveInHistory(1);
|
|
return true;
|
|
} else if (keyCode == 266) {
|
|
this.minecraft.gui.getChat().scrollChat(this.minecraft.gui.getChat().getLinesPerPage() - 1);
|
|
return true;
|
|
} else if (keyCode == 267) {
|
|
this.minecraft.gui.getChat().scrollChat(-this.minecraft.gui.getChat().getLinesPerPage() + 1);
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) {
|
|
scrollY = Mth.clamp(scrollY, -1.0, 1.0);
|
|
if (this.commandSuggestions.mouseScrolled(scrollY)) {
|
|
return true;
|
|
} else {
|
|
if (!hasShiftDown()) {
|
|
scrollY *= 7.0;
|
|
}
|
|
|
|
this.minecraft.gui.getChat().scrollChat((int)scrollY);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
|
if (this.commandSuggestions.mouseClicked((int)mouseX, (int)mouseY, button)) {
|
|
return true;
|
|
} else {
|
|
if (button == 0) {
|
|
ChatComponent chatComponent = this.minecraft.gui.getChat();
|
|
if (chatComponent.handleChatQueueClicked(mouseX, mouseY)) {
|
|
return true;
|
|
}
|
|
|
|
Style style = this.getComponentStyleAt(mouseX, mouseY);
|
|
if (style != null && this.handleComponentClicked(style)) {
|
|
this.initial = this.input.getValue();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return this.input.mouseClicked(mouseX, mouseY, button) ? true : super.mouseClicked(mouseX, mouseY, button);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void insertText(String text, boolean overwrite) {
|
|
if (overwrite) {
|
|
this.input.setValue(text);
|
|
} else {
|
|
this.input.insertText(text);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Input is relative and is applied directly to the sentHistoryCursor so -1 is the previous message, 1 is the next message from the current cursor position.
|
|
*/
|
|
public void moveInHistory(int msgPos) {
|
|
int i = this.historyPos + msgPos;
|
|
int j = this.minecraft.gui.getChat().getRecentChat().size();
|
|
i = Mth.clamp(i, 0, j);
|
|
if (i != this.historyPos) {
|
|
if (i == j) {
|
|
this.historyPos = j;
|
|
this.input.setValue(this.historyBuffer);
|
|
} else {
|
|
if (this.historyPos == j) {
|
|
this.historyBuffer = this.input.getValue();
|
|
}
|
|
|
|
this.input.setValue(this.minecraft.gui.getChat().getRecentChat().get(i));
|
|
this.commandSuggestions.setAllowSuggestions(false);
|
|
this.historyPos = i;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
|
|
this.minecraft.gui.getChat().render(guiGraphics, this.minecraft.gui.getGuiTicks(), mouseX, mouseY, true);
|
|
guiGraphics.fill(2, this.height - 14, this.width - 2, this.height - 2, this.minecraft.options.getBackgroundColor(Integer.MIN_VALUE));
|
|
this.input.render(guiGraphics, mouseX, mouseY, partialTick);
|
|
super.render(guiGraphics, mouseX, mouseY, partialTick);
|
|
guiGraphics.pose().pushPose();
|
|
guiGraphics.pose().translate(0.0F, 0.0F, 200.0F);
|
|
this.commandSuggestions.render(guiGraphics, mouseX, mouseY);
|
|
guiGraphics.pose().popPose();
|
|
GuiMessageTag guiMessageTag = this.minecraft.gui.getChat().getMessageTagAt(mouseX, mouseY);
|
|
if (guiMessageTag != null && guiMessageTag.text() != null) {
|
|
guiGraphics.renderTooltip(this.font, this.font.split(guiMessageTag.text(), 210), mouseX, mouseY);
|
|
} else {
|
|
Style style = this.getComponentStyleAt(mouseX, mouseY);
|
|
if (style != null && style.getHoverEvent() != null) {
|
|
guiGraphics.renderComponentHoverEffect(this.font, style, mouseX, mouseY);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void renderBackground(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
|
|
}
|
|
|
|
@Override
|
|
public boolean isPauseScreen() {
|
|
return false;
|
|
}
|
|
|
|
private void setChatLine(String chatLine) {
|
|
this.input.setValue(chatLine);
|
|
}
|
|
|
|
@Override
|
|
protected void updateNarrationState(NarrationElementOutput output) {
|
|
output.add(NarratedElementType.TITLE, this.getTitle());
|
|
output.add(NarratedElementType.USAGE, USAGE_TEXT);
|
|
String string = this.input.getValue();
|
|
if (!string.isEmpty()) {
|
|
output.nest().add(NarratedElementType.TITLE, Component.translatable("chat_screen.message", string));
|
|
}
|
|
}
|
|
|
|
@Nullable
|
|
private Style getComponentStyleAt(double mouseX, double mouseY) {
|
|
return this.minecraft.gui.getChat().getClickedComponentStyleAt(mouseX, mouseY);
|
|
}
|
|
|
|
public void handleChatInput(String message, boolean addToRecentChat) {
|
|
message = this.normalizeChatMessage(message);
|
|
if (!message.isEmpty()) {
|
|
if (addToRecentChat) {
|
|
this.minecraft.gui.getChat().addRecentChat(message);
|
|
}
|
|
|
|
if (message.startsWith("/")) {
|
|
this.minecraft.player.connection.sendCommand(message.substring(1));
|
|
} else {
|
|
this.minecraft.player.connection.sendChat(message);
|
|
}
|
|
}
|
|
}
|
|
|
|
public String normalizeChatMessage(String message) {
|
|
return StringUtil.trimChatMessage(StringUtils.normalizeSpace(message.trim()));
|
|
}
|
|
}
|