package io.gitlab.jfronny.libjf.config.impl.ui.tiny; import io.gitlab.jfronny.commons.throwable.Try; import io.gitlab.jfronny.libjf.LibJf; import io.gitlab.jfronny.libjf.config.api.v1.ConfigCategory; import io.gitlab.jfronny.libjf.config.api.v1.ConfigInstance; import io.gitlab.jfronny.libjf.config.api.v1.ui.tiny.WidgetFactory; import io.gitlab.jfronny.libjf.config.impl.entrypoint.JfConfigSafe; import io.gitlab.jfronny.libjf.config.impl.ui.tiny.entry.EntryInfoWidgetBuilder; import io.gitlab.jfronny.libjf.config.impl.ui.tiny.entry.EntryListWidget; import io.gitlab.jfronny.libjf.config.impl.ui.tiny.presets.PresetsScreen; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.resource.language.I18n; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.screen.ScreenTexts; import net.minecraft.text.MutableText; import net.minecraft.text.Text; import java.util.*; @Environment(EnvType.CLIENT) public class TinyConfigScreen extends Screen { public TinyConfigScreen(ConfigCategory config, Screen parent) { super(getTitle(config.getTranslationPrefix())); this.parent = parent; this.config = config; this.widgets = EntryInfoWidgetBuilder.buildWidgets(config); this.translationPrefix = config.getTranslationPrefix(); } public static Text getTitle(String categoryPath) { final String titlePath = categoryPath + "title"; if (JfConfigSafe.TRANSLATION_SUPPLIER.apply(titlePath) != null) { return Text.translatable(titlePath); } final String alternatePath = categoryPath.length() == 0 ? "" : categoryPath.substring(0, categoryPath.length() - 1); if (JfConfigSafe.TRANSLATION_SUPPLIER.apply(alternatePath) != null) { return Text.translatable(alternatePath); } return Text.translatable(titlePath); } private final String translationPrefix; private final Screen parent; private final ConfigCategory config; private final List> widgets; private EntryListWidget list; @Override protected void init() { super.init(); config.fix(); for (WidgetState widget : widgets) { widget.updateCache(); } if (!config.getPresets().isEmpty()) { this.addDrawableChild(ButtonWidget.builder(Text.translatable("libjf-config-v1.presets"), button -> Objects.requireNonNull(client).setScreen(new PresetsScreen(this, config))) .position(4, 6) .size(80, 20) .build()); } this.addDrawableChild(ButtonWidget.builder(ScreenTexts.CANCEL, button -> Objects.requireNonNull(client).setScreen(parent)) .position(this.width / 2 - 154, this.height - 28) .size(150, 20) .build()); ButtonWidget done = this.addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, (button) -> { for (WidgetState state : widgets) { Try.orElse(state::writeToEntry, e -> LibJf.LOGGER.error("Could not write config data to class", e)); } config.getRoot().write(); Objects.requireNonNull(client).setScreen(parent); }) .position(this.width / 2 + 4, this.height - 28) .size(150, 20) .build()); this.list = new EntryListWidget(this.client, this.width, this.height, 32, this.height - 32, 25); this.addSelectableChild(this.list); for (Map.Entry entry : config.getCategories().entrySet()) { this.list.addReference(width / 2, getTitle(entry.getValue().getTranslationPrefix()), () -> new TinyConfigScreen(entry.getValue(), this)); } for (WidgetState info : widgets) { MutableText name = Text.translatable(translationPrefix + info.entry.getName()); WidgetFactory.Widget control = info.factory.build(width, textRenderer, done); ButtonWidget resetButton = ButtonWidget.builder(Text.translatable("libjf-config-v1.reset"), (button -> { info.reset(); control.updateControls().run(); })) .position(width - 155, 0) .size(40, 20) .build(); this.list.addButton(control.control(), resetButton, () -> { boolean visible = !Objects.equals(info.entry.getDefault(), info.cachedValue); resetButton.active = visible; return visible; }, name); } for (ConfigInstance ci : config.getReferencedConfigs()) { if (ci != null) { this.list.addReference(width / 2, Text.translatable("libjf-config-v1.see-also", getTitle(ci.getTranslationPrefix())), () -> new TinyConfigScreen(ci, this)); } } } @Override public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { this.renderBackground(matrices); this.list.render(matrices, mouseX, mouseY, delta); drawCenteredTextWithShadow(matrices, textRenderer, title, width / 2, 15, 0xFFFFFF); Optional hovered = list.getHoveredEntryTitle(mouseY); if (hovered.isPresent()) { for (WidgetState info : widgets) { Text text = hovered.get(); MutableText name = Text.translatable(this.translationPrefix + info.entry.getName()); boolean showTooltip = text.equals(name); String tooltipKey = translationPrefix + info.entry.getName() + ".tooltip"; if (showTooltip && info.error != null) { showTooltip = false; renderTooltip(matrices, info.error.right(), mouseX, mouseY); } if (showTooltip && I18n.hasTranslation(tooltipKey)) { showTooltip = false; List list = new ArrayList<>(); for (String str : I18n.translate(tooltipKey).split("\n")) list.add(Text.literal(str)); renderTooltip(matrices, list, mouseX, mouseY); } } } super.render(matrices,mouseX,mouseY,delta); } @Override public void close() { Objects.requireNonNull(client).setScreen(parent); } }