diff options
author | isXander <xandersmith2008@gmail.com> | 2023-06-03 23:10:03 +0100 |
---|---|---|
committer | isXander <xandersmith2008@gmail.com> | 2023-06-04 16:25:09 +0100 |
commit | 3e36feeef60e56ef8cb7f737ac8eeab9fbcd6abb (patch) | |
tree | f9c3395b4da2235681b87a35ac5056a0724a181b /common/src/main/java/dev/isxander/yacl3/gui/tab | |
parent | d00a486d3bdf6105f8ca8af1034c384058b8c832 (diff) | |
download | YetAnotherConfigLib-3e36feeef60e56ef8cb7f737ac8eeab9fbcd6abb.tar.gz YetAnotherConfigLib-3e36feeef60e56ef8cb7f737ac8eeab9fbcd6abb.tar.bz2 YetAnotherConfigLib-3e36feeef60e56ef8cb7f737ac8eeab9fbcd6abb.zip |
Change package and modid to yacl3 and yet_another_config_lib_3 respectively
Diffstat (limited to 'common/src/main/java/dev/isxander/yacl3/gui/tab')
3 files changed, 235 insertions, 0 deletions
diff --git a/common/src/main/java/dev/isxander/yacl3/gui/tab/ListHolderWidget.java b/common/src/main/java/dev/isxander/yacl3/gui/tab/ListHolderWidget.java new file mode 100644 index 0000000..5059874 --- /dev/null +++ b/common/src/main/java/dev/isxander/yacl3/gui/tab/ListHolderWidget.java @@ -0,0 +1,116 @@ +package dev.isxander.yacl3.gui.tab; + +import com.google.common.collect.ImmutableList; +import dev.isxander.yacl3.gui.ElementListWidgetExt; +import net.minecraft.client.gui.ComponentPath; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.components.events.ContainerEventHandler; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.narration.NarrationElementOutput; +import net.minecraft.client.gui.navigation.FocusNavigationEvent; +import net.minecraft.client.gui.navigation.ScreenRectangle; +import net.minecraft.network.chat.CommonComponents; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.function.Supplier; + +public class ListHolderWidget<T extends ElementListWidgetExt<?>> extends AbstractWidget implements ContainerEventHandler { + private final Supplier<ScreenRectangle> dimensions; + private final T list; + + public ListHolderWidget(Supplier<ScreenRectangle> dimensions, T list) { + super(0, 0, 100, 0, CommonComponents.EMPTY); + this.dimensions = dimensions; + this.list = list; + } + + @Override + public void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float deltaTick) { + ScreenRectangle dimensions = this.dimensions.get(); + this.setX(dimensions.left()); + this.setY(dimensions.top()); + this.width = dimensions.width(); + this.height = dimensions.height(); + this.list.updateDimensions(dimensions); + this.list.render(guiGraphics, mouseX, mouseY, deltaTick); + } + + @Override + protected void updateWidgetNarration(NarrationElementOutput output) { + this.list.updateNarration(output); + } + + @Override + public List<? extends GuiEventListener> children() { + return ImmutableList.of(this.list); + } + + public T getList() { + return list; + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + return this.list.mouseClicked(mouseX, mouseY, button); + } + + @Override + public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { + return this.list.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); + } + + @Override + public boolean mouseReleased(double mouseX, double mouseY, int button) { + return this.list.mouseReleased(mouseX, mouseY, button); + } + + @Override + public boolean mouseScrolled(double mouseX, double mouseY, double amount) { + return this.list.mouseScrolled(mouseX, mouseY, amount); + } + + @Override + public boolean keyPressed(int i, int j, int k) { + return this.list.keyPressed(i, j, k); + } + + @Override + public boolean charTyped(char c, int i) { + return this.list.charTyped(c, i); + } + + @Override + public boolean isDragging() { + return this.list.isDragging(); + } + + @Override + public void setDragging(boolean dragging) { + this.list.setDragging(dragging); + } + + @Nullable + @Override + public GuiEventListener getFocused() { + return this.list.getFocused(); + } + + @Override + public void setFocused(@Nullable GuiEventListener listener) { + this.list.setFocused(listener); + } + + @Nullable + @Override + public ComponentPath nextFocusPath(FocusNavigationEvent event) { + return this.list.nextFocusPath(event); + } + + @Nullable + @Override + public ComponentPath getCurrentFocusPath() { + return this.list.getCurrentFocusPath(); + } +} diff --git a/common/src/main/java/dev/isxander/yacl3/gui/tab/ScrollableNavigationBar.java b/common/src/main/java/dev/isxander/yacl3/gui/tab/ScrollableNavigationBar.java new file mode 100644 index 0000000..199845d --- /dev/null +++ b/common/src/main/java/dev/isxander/yacl3/gui/tab/ScrollableNavigationBar.java @@ -0,0 +1,110 @@ +package dev.isxander.yacl3.gui.tab; + +import com.google.common.collect.ImmutableList; +import net.minecraft.client.Minecraft; +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.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 width, TabManager tabManager, Iterable<? extends Tab> tabs) { + super(width, tabManager, ImmutableList.copyOf(tabs)); + + // add tab tooltips to the tab buttons + for (TabButton tabButton : this.tabButtons) { + if (tabButton.tab() instanceof TabExt tab) { + tabButton.setTooltip(tab.getTooltip()); + } + } + } + + @Override + public void arrangeElements() { + int noScrollWidth = this.width - NAVBAR_MARGIN*2; + + // first pass: set the width of each tab button + for (TabButton tabButton : this.tabButtons) { + tabButton.setWidth(font.width(tabButton.getMessage()) + 10); + } + + // second pass: redistribute remaining width evenly + for (TabButton tabButton : tabButtons) { + int totalWidth = tabButtons.stream().mapToInt(AbstractWidget::getWidth).sum(); + int remainingWidth = noScrollWidth - totalWidth; + if (remainingWidth > 0) { + int extra = remainingWidth / tabButtons.size(); + tabButton.setWidth(tabButton.getWidth() + extra); + } + } + + this.layout.arrangeElements(); + this.layout.setY(0); + this.scrollOffset = 0; + + int allTabsWidth = this.tabButtons.stream().mapToInt(AbstractWidget::getWidth).sum(); + this.layout.setX(Math.max((this.width - allTabsWidth) / 2, NAVBAR_MARGIN)); + this.maxScrollOffset = Math.max(0, allTabsWidth - noScrollWidth); + } + + @Override + public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) { + graphics.pose().pushPose(); + // render option list BELOW the navbar without need to scissor + graphics.pose().translate(0, 0, 10); + + super.render(graphics, mouseX, mouseY, delta); + + graphics.pose().popPose(); + } + + @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); + } + + public int getScrollOffset() { + return 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))); + } + } +} diff --git a/common/src/main/java/dev/isxander/yacl3/gui/tab/TabExt.java b/common/src/main/java/dev/isxander/yacl3/gui/tab/TabExt.java new file mode 100644 index 0000000..3b29594 --- /dev/null +++ b/common/src/main/java/dev/isxander/yacl3/gui/tab/TabExt.java @@ -0,0 +1,9 @@ +package dev.isxander.yacl3.gui.tab; + +import net.minecraft.client.gui.components.Tooltip; +import net.minecraft.client.gui.components.tabs.Tab; +import org.jetbrains.annotations.Nullable; + +public interface TabExt extends Tab { + @Nullable Tooltip getTooltip(); +} |