From 17c5e0429cad0f556560e93c55eb103747f2c63e Mon Sep 17 00:00:00 2001 From: Des Herriott Date: Mon, 11 Mar 2024 15:00:33 +0000 Subject: [PATCH] chore: added KeyReferenceScreen (pulled from FTB Quests) --- .../ui/misc/KeyReferenceScreen.java | 191 ++++++++++++++++++ .../assets/ftblibrary/lang/en_us.json | 3 +- 2 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 common/src/main/java/dev/ftb/mods/ftblibrary/ui/misc/KeyReferenceScreen.java diff --git a/common/src/main/java/dev/ftb/mods/ftblibrary/ui/misc/KeyReferenceScreen.java b/common/src/main/java/dev/ftb/mods/ftblibrary/ui/misc/KeyReferenceScreen.java new file mode 100644 index 00000000..26b817c1 --- /dev/null +++ b/common/src/main/java/dev/ftb/mods/ftblibrary/ui/misc/KeyReferenceScreen.java @@ -0,0 +1,191 @@ +package dev.ftb.mods.ftblibrary.ui.misc; + +import dev.ftb.mods.ftblibrary.icon.Color4I; +import dev.ftb.mods.ftblibrary.icon.Icons; +import dev.ftb.mods.ftblibrary.ui.*; +import dev.ftb.mods.ftblibrary.ui.input.MouseButton; +import net.minecraft.ChatFormatting; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.resources.language.I18n; +import net.minecraft.network.chat.Component; +import net.minecraft.util.FormattedCharSequence; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.ArrayList; +import java.util.List; + +public class KeyReferenceScreen extends BaseScreen { + private final Panel textPanel; + private final PanelScrollBar scrollBar; + private final SimpleTextButton closeButton; + private final String[] translationKeys; + + private static final int SCROLLBAR_WIDTH = 16; + private static final int GUTTER_SIZE = 2; + + public KeyReferenceScreen(String... translationKeys) { + this.translationKeys = translationKeys; + + textPanel = new TextPanel(this); + + closeButton = new SimpleTextButton(this, Component.translatable("gui.close"), Icons.CLOSE) { + @Override + public void onClicked(MouseButton button) { + onBack(); + } + }; + scrollBar = new PanelScrollBar(this, textPanel); + } + + @Override + public boolean onInit() { + return setSizeProportional(0.75f, 0.8f); + } + + @Override + public Theme getTheme() { + return NordTheme.THEME; + } + + @Override + public void addWidgets() { + add(textPanel); + add(scrollBar); + add(closeButton); + } + + @Override + public void alignWidgets() { + int textPanelWidth = getGui().width - GUTTER_SIZE * 3 - SCROLLBAR_WIDTH; + + textPanel.setPosAndSize(GUTTER_SIZE, GUTTER_SIZE, textPanelWidth, getGui().height - GUTTER_SIZE * 2); + textPanel.alignWidgets(); + + scrollBar.setPosAndSize(getGui().width - GUTTER_SIZE - SCROLLBAR_WIDTH, textPanel.getPosY(), SCROLLBAR_WIDTH, textPanel.getHeight()); + + closeButton.setPosAndSize(width + 2, 0, 20, 20); + } + + @Override + public Component getTitle() { + return Component.translatable("ftblibrary.gui.key_reference"); + } + + @Override + public void drawBackground(GuiGraphics graphics, Theme theme, int x, int y, int w, int h) { + theme.drawGui(graphics, x, y, w, h, WidgetType.NORMAL); + + int w1 = theme.getStringWidth(getTitle()); + theme.drawString(graphics, getTitle(), x + (w - w1) / 2, y - theme.getFontHeight() - 1, Color4I.rgb(0x00FFFF), Theme.SHADOW); + } + + protected void drawTextBackground(GuiGraphics graphics, Theme theme, int x, int y, int w, int h) { + theme.drawPanelBackground(graphics, x, y, w, h); + } + + private static List> buildText(String... translationKeys) { + List> res = new ArrayList<>(); + for (String translationKey: translationKeys) { + for (String line : I18n.get(translationKey).split("\\n")) { + String[] parts = line.split(";", 2); + switch (parts.length) { + case 0 -> res.add(Pair.of(Component.empty(), Component.empty())); + case 1 -> res.add(Pair.of(Component.literal(parts[0]).withStyle(ChatFormatting.YELLOW, ChatFormatting.UNDERLINE), Component.empty())); + default -> res.add(Pair.of(Component.literal(parts[0]), Component.literal(parts[1]).withStyle(ChatFormatting.GRAY))); + } + } + res.add(Pair.of(Component.empty(), Component.empty())); + } + return res; + } + + private class TextPanel extends Panel { + private final TwoColumnList textWidget; + + public TextPanel(Panel panel) { + super(panel); + + textWidget = new TwoColumnList(this, buildText(translationKeys)); + } + + @Override + public void addWidgets() { + add(textWidget); + } + + @Override + public void alignWidgets() { + align(WidgetLayout.VERTICAL); + + textWidget.setPos(4, 2); + textWidget.setWidth(width); + } + + @Override + public void drawBackground(GuiGraphics graphics, Theme theme, int x, int y, int w, int h) { + drawTextBackground(graphics, theme, x, y, w, h); + } + } + + private static class TwoColumnList extends Widget { + private final int widestL; + private final List> data; + private final List> reflowed = new ArrayList<>(); + + public TwoColumnList(Panel p, List> data) { + super(p); + + this.data = data; + this.widestL = data.stream() + .map(e -> getGui().getTheme().getStringWidth(e.getLeft())) + .max(Integer::compareTo) + .orElse(0); + } + + @Override + public void setWidth(int v) { + super.setWidth(v); + + reflowText(); + } + + private void reflowText() { + Theme theme = getGui().getTheme(); + int h = 0; + int maxWidth = getParent().getWidth() - GUTTER_SIZE * 2; + reflowed.clear(); + for (var entry : data) { + if (entry.getRight().getString().isEmpty()) { + // header line + reflowed.add(Pair.of(entry.getLeft(), null)); + h += theme.getFontHeight() + 3; + } else { + var l = theme.getFont().split(entry.getRight(), maxWidth - 10 - widestL); + reflowed.add(Pair.of(entry.getLeft(), l.get(0))); + for (int i = 1; i < l.size(); i++) { + reflowed.add(Pair.of(Component.empty(), l.get(i))); + } + h += (theme.getFontHeight() + 1) * l.size(); + } + } + + height = h; + } + + @Override + public void draw(GuiGraphics graphics, Theme theme, int x, int y, int w, int h) { + int yPos = y; + + for (var entry : reflowed) { + boolean header = entry.getRight() == null; + int leftWidth = theme.getStringWidth(entry.getLeft()); + int xOff = header ? (width - leftWidth) / 2 : widestL - leftWidth - 2; + theme.drawString(graphics, entry.getLeft(), x + xOff, yPos); + if (!header) { + theme.drawString(graphics, entry.getRight(), x + widestL + 10, yPos); + } + yPos += theme.getFontHeight() + (header ? 3 : 1); + } + } + } +} diff --git a/common/src/main/resources/assets/ftblibrary/lang/en_us.json b/common/src/main/resources/assets/ftblibrary/lang/en_us.json index 2afefd34..81b1c903 100644 --- a/common/src/main/resources/assets/ftblibrary/lang/en_us.json +++ b/common/src/main/resources/assets/ftblibrary/lang/en_us.json @@ -72,5 +72,6 @@ "ftblibrary.gui.nbt_copied": "NBT copied to clipboard", "ftblibrary.gui.edit_tag_name": "Edit Tag Name", "ftblibrary.gui.edit_tag_value": "Edit Tag Value", - "ftblibrary.gui.no_selection": "Nothing Selected" + "ftblibrary.gui.no_selection": "Nothing Selected", + "ftblibrary.gui.key_reference": "Key Reference" } \ No newline at end of file