252 lines
		
	
	
	
		
			8.2 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			252 lines
		
	
	
	
		
			8.2 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.addRenderableWidget(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) {
 | |
| 		guiGraphics.fill(2, this.height - 14, this.width - 2, this.height - 2, this.minecraft.options.getBackgroundColor(Integer.MIN_VALUE));
 | |
| 		this.minecraft.gui.getChat().render(guiGraphics, this.minecraft.gui.getGuiTicks(), mouseX, mouseY, true);
 | |
| 		super.render(guiGraphics, mouseX, mouseY, partialTick);
 | |
| 		this.commandSuggestions.render(guiGraphics, mouseX, mouseY);
 | |
| 		GuiMessageTag guiMessageTag = this.minecraft.gui.getChat().getMessageTagAt(mouseX, mouseY);
 | |
| 		if (guiMessageTag != null && guiMessageTag.text() != null) {
 | |
| 			guiGraphics.setTooltipForNextFrame(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()));
 | |
| 	}
 | |
| }
 |