From ead0b794ac57e9ab2558338f7f3da7545d2e12ff Mon Sep 17 00:00:00 2001 From: isXander Date: Mon, 22 May 2023 19:33:00 +0100 Subject: scrollable navbar, group descriptions, auto-scroll descriptions --- .../isxander/yacl/gui/ScrollableNavigationBar.java | 79 ++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 common/src/main/java/dev/isxander/yacl/gui/ScrollableNavigationBar.java (limited to 'common/src/main/java/dev/isxander/yacl/gui/ScrollableNavigationBar.java') diff --git a/common/src/main/java/dev/isxander/yacl/gui/ScrollableNavigationBar.java b/common/src/main/java/dev/isxander/yacl/gui/ScrollableNavigationBar.java new file mode 100644 index 0000000..e2d9ab8 --- /dev/null +++ b/common/src/main/java/dev/isxander/yacl/gui/ScrollableNavigationBar.java @@ -0,0 +1,79 @@ +package dev.isxander.yacl.gui; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.components.TabButton; +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.util.Mth; +import org.jetbrains.annotations.Nullable; + +public class ScrollableNavigationBar extends TabNavigationBar { + private static final int NAVBAR_MARGIN = 28; + + private static final Font font = Minecraft.getInstance().font; + + private int scrollOffset; + private int maxScrollOffset; + + public ScrollableNavigationBar(int i, TabManager tabManager, Iterable iterable) { + super(i, tabManager, iterable); + } + + @Override + public void arrangeElements() { + int noScrollWidth = this.width - NAVBAR_MARGIN*2; + int minimumSize = tabButtons.stream() + .map(AbstractWidget::getMessage) + .mapToInt(label -> font.width(label) + 3) + .min().orElse(0); + int singleTabWidth = Math.max(noScrollWidth / Math.min(this.tabButtons.size(), 3), minimumSize); + for (TabButton tabButton : this.tabButtons) { + tabButton.setWidth(singleTabWidth); + } + + this.layout.arrangeElements(); + this.layout.setY(0); + this.scrollOffset = 0; + + int allTabsWidth = singleTabWidth * this.tabButtons.size(); + this.layout.setX(Math.max((this.width - allTabsWidth) / 2, NAVBAR_MARGIN)); + this.maxScrollOffset = Math.max(0, allTabsWidth - noScrollWidth); + } + + @Override + public boolean mouseScrolled(double mouseX, double mouseY, double amount) { + this.setScrollOffset(this.scrollOffset - (int)(amount*10)); + return true; + } + + @Override + public boolean isMouseOver(double mouseX, double mouseY) { + return mouseY <= 24; + } + + public void setScrollOffset(int scrollOffset) { + layout.setX(layout.getX() + this.scrollOffset); + this.scrollOffset = Mth.clamp(scrollOffset, 0, maxScrollOffset); + layout.setX(layout.getX() - this.scrollOffset); + } + + @Override + public void setFocused(@Nullable GuiEventListener child) { + super.setFocused(child); + if (child instanceof TabButton tabButton) { + this.ensureVisible(tabButton); + } + } + + protected void ensureVisible(TabButton tabButton) { + if (tabButton.getX() < NAVBAR_MARGIN) { + this.setScrollOffset(this.scrollOffset - (NAVBAR_MARGIN - tabButton.getX())); + } else if (tabButton.getX() + tabButton.getWidth() > this.width - NAVBAR_MARGIN) { + this.setScrollOffset(this.scrollOffset + (tabButton.getX() + tabButton.getWidth() - (this.width - NAVBAR_MARGIN))); + } + } +} -- cgit