aboutsummaryrefslogtreecommitdiff
path: root/common/src/main/java/dev/isxander/yacl/gui/YACLScreen.java
diff options
context:
space:
mode:
authorisXander <xandersmith2008@gmail.com>2023-05-21 12:41:45 +0100
committerisXander <xandersmith2008@gmail.com>2023-05-21 12:41:45 +0100
commit21afea0da3956f2d8cca81a54fa9820152e0c077 (patch)
treee5944f94a5f85d3fcbe048da633e62f5357fe835 /common/src/main/java/dev/isxander/yacl/gui/YACLScreen.java
parente51af159ba3eba5ebda976bea1c1957cddeee7c6 (diff)
downloadYetAnotherConfigLib-21afea0da3956f2d8cca81a54fa9820152e0c077.tar.gz
YetAnotherConfigLib-21afea0da3956f2d8cca81a54fa9820152e0c077.tar.bz2
YetAnotherConfigLib-21afea0da3956f2d8cca81a54fa9820152e0c077.zip
Start overhauling UI
Diffstat (limited to 'common/src/main/java/dev/isxander/yacl/gui/YACLScreen.java')
-rw-r--r--common/src/main/java/dev/isxander/yacl/gui/YACLScreen.java315
1 files changed, 188 insertions, 127 deletions
diff --git a/common/src/main/java/dev/isxander/yacl/gui/YACLScreen.java b/common/src/main/java/dev/isxander/yacl/gui/YACLScreen.java
index b3e614f..77090c8 100644
--- a/common/src/main/java/dev/isxander/yacl/gui/YACLScreen.java
+++ b/common/src/main/java/dev/isxander/yacl/gui/YACLScreen.java
@@ -2,10 +2,7 @@ package dev.isxander.yacl.gui;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
-import dev.isxander.yacl.api.Option;
-import dev.isxander.yacl.api.OptionFlag;
-import dev.isxander.yacl.api.PlaceholderCategory;
-import dev.isxander.yacl.api.YetAnotherConfigLib;
+import dev.isxander.yacl.api.*;
import dev.isxander.yacl.api.utils.Dimension;
import dev.isxander.yacl.api.utils.MutableDimension;
import dev.isxander.yacl.api.utils.OptionUtils;
@@ -14,117 +11,81 @@ import dev.isxander.yacl.impl.utils.YACLConstants;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
+import net.minecraft.client.gui.components.AbstractWidget;
+import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.MultiLineLabel;
+import net.minecraft.client.gui.components.Tooltip;
import net.minecraft.client.gui.components.events.GuiEventListener;
+import net.minecraft.client.gui.components.tabs.Tab;
+import net.minecraft.client.gui.components.tabs.TabManager;
+import net.minecraft.client.gui.components.tabs.TabNavigationBar;
+import net.minecraft.client.gui.navigation.ScreenRectangle;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.tooltip.TooltipRenderUtil;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
+import net.minecraft.resources.ResourceLocation;
+import java.io.*;
import java.util.HashSet;
+import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
public class YACLScreen extends Screen {
public final YetAnotherConfigLib config;
- private int currentCategoryIdx;
private final Screen parent;
- public OptionListWidget optionList;
- public CategoryListWidget categoryList;
- public TooltipButtonWidget finishedSaveButton, cancelResetButton, undoButton;
- public SearchFieldWidget searchFieldWidget;
+ public final TabManager tabManager = new TabManager(this::addRenderableWidget, this::removeWidget);
+ public TabNavigationBar tabNavigationBar;
+ public Tab[] tabs;
+ public ScreenRectangle tabArea;
public Component saveButtonMessage, saveButtonTooltipMessage;
private int saveButtonMessageTime;
-
public YACLScreen(YetAnotherConfigLib config, Screen parent) {
super(config.title());
this.config = config;
this.parent = parent;
- this.currentCategoryIdx = 0;
}
@Override
protected void init() {
- int columnWidth = width / 3;
- int padding = columnWidth / 20;
- columnWidth = Math.min(columnWidth, 400);
- int paddedWidth = columnWidth - padding * 2;
-
- MutableDimension<Integer> actionDim = Dimension.ofInt(width / 3 / 2, height - padding - 20, paddedWidth, 20);
- finishedSaveButton = new TooltipButtonWidget(
- this,
- actionDim.x() - actionDim.width() / 2,
- actionDim.y(),
- actionDim.width(),
- actionDim.height(),
- Component.empty(),
- Component.empty(),
- btn -> finishOrSave()
- );
- actionDim.expand(-actionDim.width() / 2 - 2, 0).move(-actionDim.width() / 2 - 2, -22);
- cancelResetButton = new TooltipButtonWidget(
- this,
- actionDim.x() - actionDim.width() / 2,
- actionDim.y(),
- actionDim.width(),
- actionDim.height(),
- Component.empty(),
- Component.empty(),
- btn -> cancelOrReset()
- );
- actionDim.move(actionDim.width() + 4, 0);
- undoButton = new TooltipButtonWidget(
- this,
- actionDim.x() - actionDim.width() / 2,
- actionDim.y(),
- actionDim.width(),
- actionDim.height(),
- Component.translatable("yacl.gui.undo"),
- Component.translatable("yacl.gui.undo.tooltip"),
- btn -> undo()
- );
-
- searchFieldWidget = new SearchFieldWidget(
- this,
- font,
- width / 3 / 2 - paddedWidth / 2 + 1,
- undoButton.getY() - 22,
- paddedWidth - 2, 18,
- Component.translatable("gui.recipebook.search_hint"),
- Component.translatable("gui.recipebook.search_hint")
- );
-
- categoryList = new CategoryListWidget(minecraft, this, width, height);
- addWidget(categoryList);
-
- updateActionAvailability();
- addRenderableWidget(searchFieldWidget);
- addRenderableWidget(cancelResetButton);
- addRenderableWidget(undoButton);
- addRenderableWidget(finishedSaveButton);
-
- optionList = new OptionListWidget(this, minecraft, width, height);
- addWidget(optionList);
+ if (tabs != null) {
+ closeTabs();
+ }
+
+ tabNavigationBar = TabNavigationBar.builder(tabManager, this.width)
+ .addTabs(tabs = config.categories()
+ .stream()
+ .map(category -> {
+ if (category instanceof PlaceholderCategory placeholder)
+ return new PlaceholderTab(placeholder);
+ return new CategoryTab(category);
+ })
+ .toArray(Tab[]::new)
+ )
+ .build();
+ tabNavigationBar.selectTab(0, false);
+ tabNavigationBar.arrangeElements();
+ ScreenRectangle navBarArea = tabNavigationBar.getRectangle();
+ tabArea = new ScreenRectangle(0, navBarArea.height() - 1, this.width, this.height - navBarArea.height() + 1);
+ tabManager.setTabArea(tabArea);
+ addRenderableWidget(tabNavigationBar);
config.initConsumer().accept(this);
}
@Override
public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
- renderBackground(graphics);
+ renderDirtBackground(graphics);
super.render(graphics, mouseX, mouseY, delta);
- categoryList.render(graphics, mouseX, mouseY, delta);
- searchFieldWidget.render(graphics, mouseX, mouseY, delta);
- optionList.render(graphics, mouseX, mouseY, delta);
-
- categoryList.postRender(graphics, mouseX, mouseY, delta);
- optionList.postRender(graphics, mouseX, mouseY, delta);
for (GuiEventListener child : children()) {
if (child instanceof TooltipButtonWidget tooltipButtonWidget) {
@@ -171,54 +132,8 @@ public class YACLScreen extends Screen {
}
@Override
- public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
- if (optionList.keyPressed(keyCode, scanCode, modifiers)) {
- return true;
- }
-
- return super.keyPressed(keyCode, scanCode, modifiers);
- }
-
- @Override
- public boolean charTyped(char chr, int modifiers) {
- if (optionList.charTyped(chr, modifiers)) {
- return true;
- }
-
- return super.charTyped(chr, modifiers);
- }
-
- public void changeCategory(int idx) {
- if (idx == currentCategoryIdx)
- return;
-
- if (idx != -1 && config.categories().get(idx) instanceof PlaceholderCategory placeholderCategory) {
- minecraft.setScreen(placeholderCategory.screen().apply(minecraft, this));
- } else {
- currentCategoryIdx = idx;
- optionList.refreshOptions();
- }
- }
-
- public int getCurrentCategoryIdx() {
- return currentCategoryIdx;
- }
-
- private void updateActionAvailability() {
- boolean pendingChanges = pendingChanges();
-
- undoButton.active = pendingChanges;
- finishedSaveButton.setMessage(pendingChanges ? Component.translatable("yacl.gui.save") : GuiUtils.translatableFallback("yacl.gui.done", CommonComponents.GUI_DONE));
- finishedSaveButton.setTooltip(pendingChanges ? Component.translatable("yacl.gui.save.tooltip") : Component.translatable("yacl.gui.finished.tooltip"));
- cancelResetButton.setMessage(pendingChanges ? GuiUtils.translatableFallback("yacl.gui.cancel", CommonComponents.GUI_CANCEL) : Component.translatable("controls.reset"));
- cancelResetButton.setTooltip(pendingChanges ? Component.translatable("yacl.gui.cancel.tooltip") : Component.translatable("yacl.gui.reset.tooltip"));
- }
-
- @Override
public void tick() {
- searchFieldWidget.tick();
-
- updateActionAvailability();
+ tabManager.tickCurrent();
if (saveButtonMessage != null) {
if (saveButtonMessageTime > 140) {
@@ -227,9 +142,9 @@ public class YACLScreen extends Screen {
saveButtonMessageTime = 0;
} else {
saveButtonMessageTime++;
- finishedSaveButton.setMessage(saveButtonMessage);
+ //finishedSaveButton.setMessage(saveButtonMessage);
if (saveButtonTooltipMessage != null) {
- finishedSaveButton.setTooltip(saveButtonTooltipMessage);
+ //finishedSaveButton.setTooltip(saveButtonTooltipMessage);
}
}
}
@@ -266,6 +181,19 @@ public class YACLScreen extends Screen {
@Override
public void onClose() {
minecraft.setScreen(parent);
+ closeTabs();
+ }
+
+ private void closeTabs() {
+ for (Tab tab : tabs) {
+ if (tab instanceof Closeable closeable) {
+ try {
+ closeable.close();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
}
public static void renderMultilineTooltip(GuiGraphics graphics, Font font, MultiLineLabel text, int centerX, int yAbove, int yBelow, int screenWidth, int screenHeight) {
@@ -312,4 +240,137 @@ public class YACLScreen extends Screen {
graphics.pose().popPose();
}
}
+
+ private class CategoryTab implements Tab, Closeable {
+ private final ConfigCategory category;
+
+ private final TabListWidget<OptionListWidget> optionList;
+ private final Button saveFinishedButton;
+ private final Button cancelResetButton;
+ private final Button undoButton;
+ private final SearchFieldWidget searchField;
+ private OptionDescriptionWidget descriptionWidget;
+
+ public CategoryTab(ConfigCategory category) {
+ this.category = category;
+
+ this.optionList = new TabListWidget<>(
+ () -> new ScreenRectangle(tabArea.position(), tabArea.width() / 3 * 2 + 1, tabArea.height()),
+ new OptionListWidget(YACLScreen.this, category, minecraft, 0, 0, width / 3 * 2 + 1, height, hoveredOption -> {
+ descriptionWidget.setOptionDescription(hoveredOption.description());
+ })
+ );
+
+ int columnWidth = width / 3;
+ int padding = columnWidth / 20;
+ columnWidth = Math.min(columnWidth, 400);
+ int paddedWidth = columnWidth - padding * 2;
+ MutableDimension<Integer> actionDim = Dimension.ofInt(width / 3 * 2 + width / 6, height - padding - 20, paddedWidth, 20);
+
+ saveFinishedButton = Button.builder(Component.literal("Done"), btn -> finishOrSave())
+ .pos(actionDim.x() - actionDim.width() / 2, actionDim.y())
+ .size(actionDim.width(), actionDim.height())
+ .build();
+
+ actionDim.expand(-actionDim.width() / 2 - 2, 0).move(-actionDim.width() / 2 - 2, -22);
+ cancelResetButton = Button.builder(Component.literal("Cancel"), btn -> cancelOrReset())
+ .pos(actionDim.x() - actionDim.width() / 2, actionDim.y())
+ .size(actionDim.width(), actionDim.height())
+ .build();
+
+ actionDim.move(actionDim.width() + 4, 0);
+ undoButton = Button.builder(Component.translatable("yacl.gui.undo"), btn -> undo())
+ .pos(actionDim.x() - actionDim.width() / 2, actionDim.y())
+ .size(actionDim.width(), actionDim.height())
+ .tooltip(Tooltip.create(Component.translatable("yacl.gui.undo.tooltip")))
+ .build();
+
+ searchField = new SearchFieldWidget(
+ YACLScreen.this,
+ font,
+ width / 3 * 2 + width / 6 - paddedWidth / 2 + 1,
+ undoButton.getY() - 22,
+ paddedWidth - 2, 18,
+ Component.translatable("gui.recipebook.search_hint"),
+ Component.translatable("gui.recipebook.search_hint"),
+ searchQuery -> optionList.getList().updateSearchQuery(searchQuery)
+ );
+
+ descriptionWidget = new OptionDescriptionWidget(
+ () -> new ScreenRectangle(
+ width / 3 * 2 + padding,
+ tabArea.top() + padding,
+ paddedWidth,
+ searchField.getY() - 1 - tabArea.top() - padding * 2
+ ),
+ null
+ );
+
+ updateButtons();
+ }
+
+ @Override
+ public Component getTabTitle() {
+ return category.name();
+ }
+
+ @Override
+ public void visitChildren(Consumer<AbstractWidget> consumer) {
+ consumer.accept(optionList);
+ consumer.accept(saveFinishedButton);
+ consumer.accept(cancelResetButton);
+ consumer.accept(undoButton);
+ consumer.accept(searchField);
+ consumer.accept(descriptionWidget);
+ }
+
+ @Override
+ public void doLayout(ScreenRectangle screenRectangle) {
+
+ }
+
+ @Override
+ public void tick() {
+ updateButtons();
+ searchField.tick();
+ }
+
+ private void updateButtons() {
+ boolean pendingChanges = pendingChanges();
+
+ undoButton.active = pendingChanges;
+ saveFinishedButton.setMessage(pendingChanges ? Component.translatable("yacl.gui.save") : GuiUtils.translatableFallback("yacl.gui.done", CommonComponents.GUI_DONE));
+ saveFinishedButton.setTooltip(Tooltip.create(pendingChanges ? Component.translatable("yacl.gui.save.tooltip") : Component.translatable("yacl.gui.finished.tooltip")));
+ cancelResetButton.setMessage(pendingChanges ? GuiUtils.translatableFallback("yacl.gui.cancel", CommonComponents.GUI_CANCEL) : Component.translatable("controls.reset"));
+ cancelResetButton.setTooltip(Tooltip.create(pendingChanges ? Component.translatable("yacl.gui.cancel.tooltip") : Component.translatable("yacl.gui.reset.tooltip")));
+ }
+
+ @Override
+ public void close() {
+ descriptionWidget.close();
+ }
+ }
+
+ private class PlaceholderTab implements Tab {
+ private final PlaceholderCategory category;
+
+ public PlaceholderTab(PlaceholderCategory category) {
+ this.category = category;
+ }
+
+ @Override
+ public Component getTabTitle() {
+ return category.name();
+ }
+
+ @Override
+ public void visitChildren(Consumer<AbstractWidget> consumer) {
+
+ }
+
+ @Override
+ public void doLayout(ScreenRectangle screenRectangle) {
+ minecraft.setScreen(category.screen().apply(minecraft, YACLScreen.this));
+ }
+ }
}