219 lines
		
	
	
	
		
			6.9 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			219 lines
		
	
	
	
		
			6.9 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.client.gui.components;
 | |
| 
 | |
| import java.util.ArrayList;
 | |
| import java.util.List;
 | |
| import net.fabricmc.api.EnvType;
 | |
| import net.fabricmc.api.Environment;
 | |
| import net.minecraft.client.gui.Font;
 | |
| import net.minecraft.client.gui.GuiGraphics;
 | |
| import net.minecraft.locale.Language;
 | |
| 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.util.FormattedCharSequence;
 | |
| import net.minecraft.util.Mth;
 | |
| import org.jetbrains.annotations.Nullable;
 | |
| 
 | |
| @Environment(EnvType.CLIENT)
 | |
| public interface MultiLineLabel {
 | |
| 	MultiLineLabel EMPTY = new MultiLineLabel() {
 | |
| 		@Override
 | |
| 		public void renderCentered(GuiGraphics guiGraphics, int x, int y) {
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void renderCentered(GuiGraphics guiGraphics, int x, int y, int lineHeight, int color) {
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public void renderLeftAligned(GuiGraphics guiGraphics, int x, int y, int lineHeight, int color) {
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public int renderLeftAlignedNoShadow(GuiGraphics guiGraphics, int x, int y, int lineHeight, int color) {
 | |
| 			return y;
 | |
| 		}
 | |
| 
 | |
| 		@Nullable
 | |
| 		@Override
 | |
| 		public Style getStyleAtCentered(int x, int y, int height, double mouseX, double mouseY) {
 | |
| 			return null;
 | |
| 		}
 | |
| 
 | |
| 		@Nullable
 | |
| 		@Override
 | |
| 		public Style getStyleAtLeftAligned(int x, int y, int height, double mouseX, double mouseY) {
 | |
| 			return null;
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public int getLineCount() {
 | |
| 			return 0;
 | |
| 		}
 | |
| 
 | |
| 		@Override
 | |
| 		public int getWidth() {
 | |
| 			return 0;
 | |
| 		}
 | |
| 	};
 | |
| 
 | |
| 	static MultiLineLabel create(Font font, Component... components) {
 | |
| 		return create(font, Integer.MAX_VALUE, Integer.MAX_VALUE, components);
 | |
| 	}
 | |
| 
 | |
| 	static MultiLineLabel create(Font font, int maxWidth, Component... components) {
 | |
| 		return create(font, maxWidth, Integer.MAX_VALUE, components);
 | |
| 	}
 | |
| 
 | |
| 	static MultiLineLabel create(Font font, Component component, int maxWidth) {
 | |
| 		return create(font, maxWidth, Integer.MAX_VALUE, component);
 | |
| 	}
 | |
| 
 | |
| 	static MultiLineLabel create(Font font, int maxWidth, int maxRows, Component... components) {
 | |
| 		return components.length == 0 ? EMPTY : new MultiLineLabel() {
 | |
| 			@Nullable
 | |
| 			private List<MultiLineLabel.TextAndWidth> cachedTextAndWidth;
 | |
| 			@Nullable
 | |
| 			private Language splitWithLanguage;
 | |
| 
 | |
| 			@Override
 | |
| 			public void renderCentered(GuiGraphics guiGraphics, int x, int y) {
 | |
| 				this.renderCentered(guiGraphics, x, y, 9, -1);
 | |
| 			}
 | |
| 
 | |
| 			@Override
 | |
| 			public void renderCentered(GuiGraphics guiGraphics, int x, int y, int lineHeight, int color) {
 | |
| 				int i = y;
 | |
| 
 | |
| 				for (MultiLineLabel.TextAndWidth textAndWidth : this.getSplitMessage()) {
 | |
| 					guiGraphics.drawString(font, textAndWidth.text, x - textAndWidth.width / 2, i, color);
 | |
| 					i += lineHeight;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			@Override
 | |
| 			public void renderLeftAligned(GuiGraphics guiGraphics, int x, int y, int lineHeight, int color) {
 | |
| 				int i = y;
 | |
| 
 | |
| 				for (MultiLineLabel.TextAndWidth textAndWidth : this.getSplitMessage()) {
 | |
| 					guiGraphics.drawString(font, textAndWidth.text, x, i, color);
 | |
| 					i += lineHeight;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			@Override
 | |
| 			public int renderLeftAlignedNoShadow(GuiGraphics guiGraphics, int x, int y, int lineHeight, int color) {
 | |
| 				int i = y;
 | |
| 
 | |
| 				for (MultiLineLabel.TextAndWidth textAndWidth : this.getSplitMessage()) {
 | |
| 					guiGraphics.drawString(font, textAndWidth.text, x, i, color, false);
 | |
| 					i += lineHeight;
 | |
| 				}
 | |
| 
 | |
| 				return i;
 | |
| 			}
 | |
| 
 | |
| 			@Nullable
 | |
| 			@Override
 | |
| 			public Style getStyleAtCentered(int x, int y, int height, double mouseX, double mouseY) {
 | |
| 				List<MultiLineLabel.TextAndWidth> list = this.getSplitMessage();
 | |
| 				int i = Mth.floor((mouseY - y) / height);
 | |
| 				if (i >= 0 && i < list.size()) {
 | |
| 					MultiLineLabel.TextAndWidth textAndWidth = (MultiLineLabel.TextAndWidth)list.get(i);
 | |
| 					int j = x - textAndWidth.width / 2;
 | |
| 					if (mouseX < j) {
 | |
| 						return null;
 | |
| 					} else {
 | |
| 						int k = Mth.floor(mouseX - j);
 | |
| 						return font.getSplitter().componentStyleAtWidth(textAndWidth.text, k);
 | |
| 					}
 | |
| 				} else {
 | |
| 					return null;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			@Nullable
 | |
| 			@Override
 | |
| 			public Style getStyleAtLeftAligned(int x, int y, int height, double mouseX, double mouseY) {
 | |
| 				if (mouseX < x) {
 | |
| 					return null;
 | |
| 				} else {
 | |
| 					List<MultiLineLabel.TextAndWidth> list = this.getSplitMessage();
 | |
| 					int i = Mth.floor((mouseY - y) / height);
 | |
| 					if (i >= 0 && i < list.size()) {
 | |
| 						MultiLineLabel.TextAndWidth textAndWidth = (MultiLineLabel.TextAndWidth)list.get(i);
 | |
| 						int j = Mth.floor(mouseX - x);
 | |
| 						return font.getSplitter().componentStyleAtWidth(textAndWidth.text, j);
 | |
| 					} else {
 | |
| 						return null;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			private List<MultiLineLabel.TextAndWidth> getSplitMessage() {
 | |
| 				Language language = Language.getInstance();
 | |
| 				if (this.cachedTextAndWidth != null && language == this.splitWithLanguage) {
 | |
| 					return this.cachedTextAndWidth;
 | |
| 				} else {
 | |
| 					this.splitWithLanguage = language;
 | |
| 					List<FormattedText> list = new ArrayList();
 | |
| 
 | |
| 					for (Component component : components) {
 | |
| 						list.addAll(font.splitIgnoringLanguage(component, maxWidth));
 | |
| 					}
 | |
| 
 | |
| 					this.cachedTextAndWidth = new ArrayList();
 | |
| 					int i = Math.min(list.size(), maxRows);
 | |
| 					List<FormattedText> list2 = list.subList(0, i);
 | |
| 
 | |
| 					for (int j = 0; j < list2.size(); j++) {
 | |
| 						FormattedText formattedText = (FormattedText)list2.get(j);
 | |
| 						FormattedCharSequence formattedCharSequence = Language.getInstance().getVisualOrder(formattedText);
 | |
| 						if (j == list2.size() - 1 && i == maxRows && i != list.size()) {
 | |
| 							FormattedText formattedText2 = font.substrByWidth(formattedText, font.width(formattedText) - font.width(CommonComponents.ELLIPSIS));
 | |
| 							FormattedText formattedText3 = FormattedText.composite(formattedText2, CommonComponents.ELLIPSIS);
 | |
| 							this.cachedTextAndWidth.add(new MultiLineLabel.TextAndWidth(Language.getInstance().getVisualOrder(formattedText3), font.width(formattedText3)));
 | |
| 						} else {
 | |
| 							this.cachedTextAndWidth.add(new MultiLineLabel.TextAndWidth(formattedCharSequence, font.width(formattedCharSequence)));
 | |
| 						}
 | |
| 					}
 | |
| 
 | |
| 					return this.cachedTextAndWidth;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			@Override
 | |
| 			public int getLineCount() {
 | |
| 				return this.getSplitMessage().size();
 | |
| 			}
 | |
| 
 | |
| 			@Override
 | |
| 			public int getWidth() {
 | |
| 				return Math.min(maxWidth, this.getSplitMessage().stream().mapToInt(MultiLineLabel.TextAndWidth::width).max().orElse(0));
 | |
| 			}
 | |
| 		};
 | |
| 	}
 | |
| 
 | |
| 	void renderCentered(GuiGraphics guiGraphics, int x, int y);
 | |
| 
 | |
| 	void renderCentered(GuiGraphics guiGraphics, int x, int y, int lineHeight, int color);
 | |
| 
 | |
| 	void renderLeftAligned(GuiGraphics guiGraphics, int x, int y, int lineHeight, int color);
 | |
| 
 | |
| 	int renderLeftAlignedNoShadow(GuiGraphics guiGraphics, int x, int y, int lineHeight, int color);
 | |
| 
 | |
| 	@Nullable
 | |
| 	Style getStyleAtCentered(int x, int y, int height, double mouseX, double mouseY);
 | |
| 
 | |
| 	@Nullable
 | |
| 	Style getStyleAtLeftAligned(int x, int y, int height, double mouseX, double mouseY);
 | |
| 
 | |
| 	int getLineCount();
 | |
| 
 | |
| 	int getWidth();
 | |
| 
 | |
| 	@Environment(EnvType.CLIENT)
 | |
| 	public record TextAndWidth(FormattedCharSequence text, int width) {
 | |
| 	}
 | |
| }
 |