diff options
| author | shedaniel <daniel@shedaniel.me> | 2022-11-12 13:26:56 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2023-05-29 21:19:41 +0800 |
| commit | de4df53457cd010003ff5ccb672d981d328d2895 (patch) | |
| tree | b4689f4d9f1632dd062c2eb907fe8eede50deca7 /runtime/src/main/java/me | |
| parent | f9ab00af5858b06c72695a375edfa9fc11d1b63a (diff) | |
| download | RoughlyEnoughItems-de4df53457cd010003ff5ccb672d981d328d2895.tar.gz RoughlyEnoughItems-de4df53457cd010003ff5ccb672d981d328d2895.tar.bz2 RoughlyEnoughItems-de4df53457cd010003ff5ccb672d981d328d2895.zip | |
Fix #1207
Diffstat (limited to 'runtime/src/main/java/me')
5 files changed, 145 insertions, 79 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java index 42d08935f..746e11b54 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java @@ -683,7 +683,7 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { @Comment("Declares how the scrollbar in composite screen should act.") private boolean compositeScrollBarPermanent = false; private boolean toastDisplayedOnCopyIdentifier = true; @Comment("Declares whether REI should use compact tabs for categories.") private boolean useCompactTabs = true; - @Comment("Declares whether REI should use compact tab buttons for categories.") @ConfigEntry.Gui.Excluded private boolean useCompactTabButtons = false; + @Comment("Declares whether REI should use compact tab buttons for categories.") private boolean useCompactTabButtons = false; } public static class Search { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/AbstractDisplayViewingScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/AbstractDisplayViewingScreen.java index 877d6c357..f904d5616 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/AbstractDisplayViewingScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/AbstractDisplayViewingScreen.java @@ -109,8 +109,8 @@ public abstract class AbstractDisplayViewingScreen extends Screen implements Dis this.categoryPages = -1; } - protected void initTabs() { - this.tabs.init(new Rectangle(bounds.x, bounds.y - 28, bounds.width, 28), categories, new IntValue() { + protected void initTabs(int width) { + this.tabs.init(new Rectangle(bounds.getCenterX() - width / 2, bounds.y - 28, width, 28), new Rectangle(bounds.getCenterX() - width / 2, bounds.y - 28, width, 28), categories, new IntValue() { @Override public void accept(int value) { AbstractDisplayViewingScreen.this.categoryPages = value; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java index e5489261a..097e90f62 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java @@ -100,10 +100,6 @@ public class CompositeDisplayViewingScreen extends AbstractDisplayViewingScreen @Override public void init() { super.init(); - boolean isCompactTabs = ConfigObject.getInstance().isUsingCompactTabs(); - boolean isCompactTabButtons = ConfigObject.getInstance().isUsingCompactTabButtons(); - int tabButtonsSize = isCompactTabButtons ? 10 : 16; - int tabSize = isCompactTabs ? 24 : 28; this.children().clear(); this.widgets.clear(); this.buttonList.clear(); @@ -116,7 +112,7 @@ public class CompositeDisplayViewingScreen extends AbstractDisplayViewingScreen int guiHeight = Mth.clamp(category.getDisplayHeight() + 40, 166, largestHeight); this.bounds = new Rectangle(width / 2 - guiWidth / 2, height / 2 - guiHeight / 2, guiWidth, guiHeight); - this.initTabs(); + this.initTabs(this.bounds.width); this.widgets.addAll(this.tabs.widgets()); List<EntryIngredient> workstations = CategoryRegistry.getInstance().get(category.getCategoryIdentifier()).getWorkstations(); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java index c18f6979e..f7e9ebf1c 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java @@ -39,6 +39,7 @@ import me.shedaniel.math.Rectangle; import me.shedaniel.math.impl.PointHelper; import me.shedaniel.rei.api.client.REIRuntime; import me.shedaniel.rei.api.client.config.ConfigObject; +import me.shedaniel.rei.api.client.gui.config.SearchFieldLocation; import me.shedaniel.rei.api.client.gui.widgets.Button; import me.shedaniel.rei.api.client.gui.widgets.Panel; import me.shedaniel.rei.api.client.gui.widgets.Widget; @@ -76,20 +77,37 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.*; +import java.util.function.Function; import java.util.function.Supplier; +import java.util.stream.Collectors; @ApiStatus.Internal public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { + private static final int INNER_PADDING_Y = 36; + private static final int OUTER_PADDING_TOP = 2; + private static final int OUTER_PADDING_BOTTOM = 2; + private static final int DISPLAY_GAP = 4; private final Map<Rectangle, Pair<DisplaySpec, List<Widget>>> recipeBounds = Maps.newHashMap(); private List<Widget> widgets = Lists.newArrayList(); public int page; @Nullable private Panel workingStationsBaseWidget; private Button recipeBack, recipeNext, categoryBack, categoryNext; + private final int bestWidthDisplay; public DefaultDisplayViewingScreen(Map<DisplayCategory<?>, List<DisplaySpec>> categoriesMap, @Nullable CategoryIdentifier<?> category) { super(categoriesMap, category); this.bounds = new Rectangle(0, 0, 176, 150); + //noinspection RedundantCast + List<Integer> list = CollectionUtils.mapAndFilter(categoriesMap.entrySet(), Objects::nonNull, entry -> ((Optional<Integer>) CollectionUtils.<DisplaySpec, Integer>mapAndMax(entry.getValue(), + display -> ((DisplayCategory<Display>) entry.getKey()).getDisplayWidth(display.provideInternalDisplay()), Comparator.naturalOrder())).orElse(null)); + list.sort(Comparator.naturalOrder()); + int mode = list.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting())).entrySet().stream() + .max(Map.Entry.comparingByValue()) + .map(Map.Entry::getKey) + .orElse(150); + int median = list.size() % 2 == 0 ? (list.get(list.size() / 2) + list.get(list.size() / 2 - 1)) / 2 : list.get(list.size() / 2); + this.bestWidthDisplay = (int) Math.round((mode * 0.5 + median * 1.5) / 2.0); } @Override @@ -134,24 +152,28 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { this.children().clear(); this.recipeBounds.clear(); this.widgets.clear(); - int largestHeight = Math.min(Math.max(height - 34 - 30, 100), ConfigObject.getInstance().getMaxRecipesPageHeight()); - int maxWidthDisplay = CollectionUtils.<DisplaySpec, Integer>mapAndMax(getCurrentDisplayed(), display -> getCurrentCategory().getDisplayWidth(display.provideInternalDisplay()), Comparator.naturalOrder()).orElse(150); +// int maxWidthDisplay = CollectionUtils.<DisplaySpec, Integer>mapAndMax(getCurrentDisplayed(), display -> getCurrentCategory().getDisplayWidth(display.provideInternalDisplay()), Comparator.naturalOrder()).orElse(150); +// int guiWidth = Math.max(maxWidthDisplay + 10 + 14 + 14, 190); + int guiWidth = Math.max(bestWidthDisplay + 10 + 14 + 14, 190); + this.tabs.initTabsSize(guiWidth); + + int topMargin = OUTER_PADDING_TOP + this.tabs.tabSize() - 2 + (categories.size() > this.tabs.tabsPerPage() ? 16 : 0); + int bottomMargin = OUTER_PADDING_BOTTOM + (ConfigObject.getInstance().getSearchFieldLocation() == SearchFieldLocation.CENTER ? 22 : 0); + int largestHeight = Math.min(Math.max(height - topMargin - bottomMargin, 100), ConfigObject.getInstance().getMaxRecipesPageHeight()); int maxHeight = Math.min(largestHeight, CollectionUtils.<DisplayCategory<?>, Integer>mapAndMax(categories, - category -> (category.getDisplayHeight() + 4) * Math.max(1, Math.min(getRecipesPerPage(largestHeight, category) + 1, Math.max(categoryMap.get(category).size(), ConfigObject.getInstance().getMaxRecipePerPage()))) + 36, Comparator.naturalOrder()).orElse(66)); - int totalDisplayHeight = (getCurrentCategory().getDisplayHeight() + 4) * Math.max(1, getRecipesPerPage(maxHeight, getCurrentCategory()) + 1) + 36; - int guiWidth = Math.max(maxWidthDisplay + 10 + 14 + 14, 190); - this.bounds = new Rectangle(width / 2 - guiWidth / 2, height / 2 - maxHeight / 2, guiWidth, maxHeight); + category -> INNER_PADDING_Y + (category.getDisplayHeight() + DISPLAY_GAP) * Math.max(1, Math.min(getRecipesPerPage(largestHeight, category) + 1, Math.max(categoryMap.get(category).size(), ConfigObject.getInstance().getMaxRecipePerPage()))), Comparator.naturalOrder()).orElse(66)); + this.bounds = new Rectangle(width / 2 - guiWidth / 2, topMargin + (height - topMargin - bottomMargin) / 2 - maxHeight / 2, guiWidth, maxHeight); - this.initTabs(); + this.initTabs(guiWidth); this.widgets.addAll(this.tabs.widgets()); this.page = Mth.clamp(page, 0, getCurrentTotalPages() - 1); - this.widgets.add(categoryBack = Widgets.createButton(new Rectangle(bounds.getX() + 5, bounds.getY() + 5, 12, 12), ImmutableTextComponent.EMPTY) + this.widgets.add(categoryBack = Widgets.createButton(new Rectangle(bounds.getCenterX() - guiWidth / 2 + 5, bounds.getY() + 5, 12, 12), ImmutableTextComponent.EMPTY) .onClick(button -> previousCategory()).tooltipLine(new TranslatableComponent("text.rei.previous_category"))); this.widgets.add(Widgets.createClickableLabel(new Point(bounds.getCenterX(), bounds.getY() + 7), getCurrentCategory().getTitle(), clickableLabelWidget -> { ViewSearchBuilder.builder().addAllCategories().open(); }).tooltip(new TranslatableComponent("text.rei.view_all_categories"))); - this.widgets.add(categoryNext = Widgets.createButton(new Rectangle(bounds.getMaxX() - 17, bounds.getY() + 5, 12, 12), ImmutableTextComponent.EMPTY) + this.widgets.add(categoryNext = Widgets.createButton(new Rectangle(bounds.getCenterX() + guiWidth / 2 - 17, bounds.getY() + 5, 12, 12), ImmutableTextComponent.EMPTY) .onClick(button -> nextCategory()).tooltipLine(new TranslatableComponent("text.rei.next_category"))); this.categoryBack.setEnabled(categories.size() > 1); this.categoryNext.setEnabled(categories.size() > 1); @@ -172,7 +194,7 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { matrices.popPose(); }), 0, 0, 1)); - this.widgets.add(recipeBack = Widgets.createButton(new Rectangle(bounds.getX() + 5, bounds.getY() + 19, 12, 12), ImmutableTextComponent.EMPTY) + this.widgets.add(recipeBack = Widgets.createButton(new Rectangle(bounds.getCenterX() - guiWidth / 2 + 5, bounds.getY() + 19, 12, 12), ImmutableTextComponent.EMPTY) .onClick(button -> { page--; if (page < 0) @@ -193,7 +215,7 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { label.setMessage(new ImmutableTextComponent(String.format("%d/%d", page + 1, getCurrentTotalPages()))); label.setClickable(getCurrentTotalPages() > 1); }).tooltipFunction(label -> label.isClickable() ? new Component[]{new TranslatableComponent("text.rei.go_back_first_page"), new TextComponent(" "), new TranslatableComponent("text.rei.shift_click_to", new TranslatableComponent("text.rei.choose_page")).withStyle(ChatFormatting.GRAY)} : null)); - this.widgets.add(recipeNext = Widgets.createButton(new Rectangle(bounds.getMaxX() - 17, bounds.getY() + 19, 12, 12), ImmutableTextComponent.EMPTY) + this.widgets.add(recipeNext = Widgets.createButton(new Rectangle(bounds.getCenterX() + guiWidth / 2 - 17, bounds.getY() + 19, 12, 12), ImmutableTextComponent.EMPTY) .onClick(button -> { page++; if (page >= getCurrentTotalPages()) @@ -206,8 +228,8 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { widgets = CollectionUtils.map(widgets, widget -> Widgets.withTranslate(widget, 0, 0, 10)); widgets.add(Widgets.withTranslate(new PanelWidget(bounds), 0, 0, 5)); widgets.add(Widgets.withTranslate(Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> { - fill(matrices, bounds.x + 17, bounds.y + 5, bounds.x + bounds.width - 17, bounds.y + 17, darkStripesColor.value().getColor()); - fill(matrices, bounds.x + 17, bounds.y + 19, bounds.x + bounds.width - 17, bounds.y + 31, darkStripesColor.value().getColor()); + fill(matrices, bounds.getCenterX() - guiWidth / 2 + 17, bounds.y + 5, bounds.getCenterX() + guiWidth / 2 - 17, bounds.y + 17, darkStripesColor.value().getColor()); + fill(matrices, bounds.getCenterX() - guiWidth / 2 + 17, bounds.y + 19, bounds.getCenterX() + guiWidth / 2 - 17, bounds.y + 31, darkStripesColor.value().getColor()); }), 0, 0, 6)); initWorkstations(widgets); @@ -222,7 +244,7 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { final DisplaySpec display = currentDisplayed.get(i); final Supplier<Display> displaySupplier = display::provideInternalDisplay; int displayWidth = getCurrentCategory().getDisplayWidth(displaySupplier.get()); - final Rectangle displayBounds = new Rectangle(getBounds().getCenterX() - displayWidth / 2, getBounds().getCenterY() + 16 - displayHeight * (getRecipesPerPage() + 1) / 2 - 2 * (getRecipesPerPage() + 1) + displayHeight * i + 4 * i, displayWidth, displayHeight); + final Rectangle displayBounds = new Rectangle(getBounds().getCenterX() - displayWidth / 2, getBounds().getCenterY() + 16 - displayHeight * (getRecipesPerPage() + 1) / 2 - 2 * (getRecipesPerPage() + 1) + displayHeight * i + DISPLAY_GAP * i, displayWidth, displayHeight); List<Widget> setupDisplay; try { setupDisplay = getCurrentCategoryView(display.provideInternalDisplay()).setupDisplay(display.provideInternalDisplay(), displayBounds); @@ -307,7 +329,7 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen { if (category.getFixedDisplaysPerPage() > 0) return category.getFixedDisplaysPerPage() - 1; int height = category.getDisplayHeight(); - return Mth.clamp(Mth.floor(((double) totalHeight - 36) / ((double) height + 4)) - 1, 0, Math.min(ConfigObject.getInstance().getMaxRecipePerPage() - 1, category.getMaximumDisplaysPerPage() - 1)); + return Mth.clamp(Mth.floor(((double) totalHeight - INNER_PADDING_Y) / ((double) height + DISPLAY_GAP)) - 1, 0, Math.min(ConfigObject.getInstance().getMaxRecipePerPage() - 1, category.getMaximumDisplaysPerPage() - 1)); } private final ValueAnimator<Color> darkStripesColor = ValueAnimator.ofColor() diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabContainerWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabContainerWidget.java index 950328d84..e67248c7b 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabContainerWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabContainerWidget.java @@ -23,30 +23,37 @@ package me.shedaniel.rei.impl.client.gui.widget; +import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.Tesselator; import dev.architectury.utils.value.IntValue; import me.shedaniel.clothconfig2.api.animator.NumberAnimator; import me.shedaniel.clothconfig2.api.animator.ValueAnimator; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.config.ConfigObject; -import me.shedaniel.rei.api.client.gui.widgets.CloseableScissors; -import me.shedaniel.rei.api.client.gui.widgets.DelegateWidget; -import me.shedaniel.rei.api.client.gui.widgets.Widget; -import me.shedaniel.rei.api.client.gui.widgets.Widgets; +import me.shedaniel.rei.api.client.gui.widgets.*; import me.shedaniel.rei.api.client.registry.display.DisplayCategory; +import me.shedaniel.rei.impl.client.gui.InternalTextures; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiComponent; import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.util.Mth; import java.util.ArrayList; -import java.util.Comparator; import java.util.List; -import java.util.stream.Stream; public class TabContainerWidget extends GuiComponent { private final Rectangle bounds = new Rectangle(); private final List<Widget> widgets = new ArrayList<>(); private final NumberAnimator<Double> scrollAnimator = ValueAnimator.ofDouble(); + private boolean isCompactTabs; + private boolean isCompactTabButtons; + private int tabSize; + private int tabButtonsSize; private int tabsPerPage = 5; public TabContainerWidget() { @@ -57,78 +64,106 @@ public class TabContainerWidget extends GuiComponent { } public void updateScroll(List<DisplayCategory<?>> categories, int selectedCategory, long duration) { - boolean isCompactTabs = ConfigObject.getInstance().isUsingCompactTabs(); - int tabSize = isCompactTabs ? 24 : 28; - - double curr = scrollAnimator.doubleValue() % (tabSize * categories.size()); - double newValue1 = selectedCategory * tabSize + Math.floor(scrollAnimator.doubleValue() / (tabSize * categories.size())) * (tabSize * categories.size()); - double newValue2 = newValue1 - (tabSize * categories.size()); - double newValue3 = newValue1 + (tabSize * categories.size()); - - Stream.of(newValue1, newValue2, newValue3).min(Comparator.comparingDouble(value -> Math.abs(value - scrollAnimator.doubleValue()))).ifPresent(newValue -> { - scrollAnimator.setTo(newValue, duration); - }); + this.initTabsVariables(); + if (categories.size() <= tabsPerPage) { + scrollAnimator.setAs(0d); + } else if (selectedCategory < tabsPerPage / 2) { + scrollAnimator.setTo(0d, duration); + } else if (selectedCategory >= categories.size() - (int) Math.ceil(tabsPerPage / 2)) { + scrollAnimator.setTo((categories.size() - tabsPerPage) * tabSize, duration); + } else { + scrollAnimator.setTo((selectedCategory - (tabsPerPage - 1) / 2.0) * tabSize, duration); + } + } + + private void initTabsVariables() { + this.isCompactTabs = ConfigObject.getInstance().isUsingCompactTabs(); + this.isCompactTabButtons = ConfigObject.getInstance().isUsingCompactTabButtons(); + this.tabSize = isCompactTabs ? 24 : 28; + this.tabButtonsSize = isCompactTabButtons ? 10 : 16; + } + + public void initTabsSize(int width) { + this.initTabsVariables(); + this.tabsPerPage = Mth.floor((width - 6) / tabSize); + if (this.tabsPerPage % 2 == 0) + this.tabsPerPage--; } - public void init(Rectangle bounds, List<DisplayCategory<?>> categories, IntValue categoryPages, IntValue selectedCategory, Runnable reInit) { + public void init(Rectangle scissorsBounds, Rectangle bounds, List<DisplayCategory<?>> categories, IntValue categoryPages, IntValue selectedCategory, Runnable reInit) { this.setBounds(bounds); this.widgets.clear(); - boolean isCompactTabs = ConfigObject.getInstance().isUsingCompactTabs(); - int tabSize = isCompactTabs ? 24 : 28; - this.tabsPerPage = Mth.floor((this.bounds.getWidth() - 10) / tabSize); + initTabsSize(bounds.width); if (categoryPages.getAsInt() == -1) { categoryPages.accept(Math.max(0, selectedCategory.getAsInt() / tabsPerPage())); } + if (categories.size() > tabsPerPage) { + Button tabLeft, tabRight; + this.widgets.add(tabLeft = Widgets.createButton(new Rectangle(bounds.x, bounds.getMaxY() - tabSize + 1 - tabButtonsSize, tabButtonsSize, tabButtonsSize), new TextComponent("")) + .onClick(button -> { + int currentCategoryPage = selectedCategory.getAsInt() / tabsPerPage(); + currentCategoryPage = Math.floorMod(currentCategoryPage - 1, categories.size() / tabsPerPage() + 1); + selectedCategory.accept(Mth.clamp(currentCategoryPage * tabsPerPage() + tabsPerPage() / 2, + tabsPerPage() / 2, categories.size() - (int) Math.ceil(tabsPerPage() / 2.0))); + }) + .tooltipLine(new TranslatableComponent("text.rei.previous_page"))); + this.widgets.add(tabRight = Widgets.createButton(new Rectangle(bounds.x + bounds.width - tabButtonsSize - (isCompactTabButtons ? 0 : 1), bounds.getMaxY() - tabSize + 1 - tabButtonsSize, tabButtonsSize, tabButtonsSize), new TextComponent("")) + .onClick(button -> { + int currentCategoryPage = selectedCategory.getAsInt() / tabsPerPage(); + currentCategoryPage = Math.floorMod(currentCategoryPage + 1, categories.size() / tabsPerPage() + 1); + selectedCategory.accept(Mth.clamp(currentCategoryPage * tabsPerPage() + tabsPerPage() / 2, + tabsPerPage() / 2, categories.size() - (int) Math.ceil(tabsPerPage() / 2.0))); + }) + .tooltipLine(new TranslatableComponent("text.rei.next_page"))); + + this.widgets.add(Widgets.withTranslate(Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> { + Rectangle tabLeftBounds = tabLeft.getBounds(); + Rectangle tabRightBounds = tabRight.getBounds(); + if (isCompactTabButtons) { + matrices.pushPose(); + matrices.translate(0, 0.5, 0); + RenderSystem.setShaderTexture(0, InternalTextures.ARROW_LEFT_SMALL_TEXTURE); + blit(matrices, tabLeftBounds.x + 2, tabLeftBounds.y + 2, 0, 0, 6, 6, 6, 6); + RenderSystem.setShaderTexture(0, InternalTextures.ARROW_RIGHT_SMALL_TEXTURE); + blit(matrices, tabRightBounds.x + 2, tabRightBounds.y + 2, 0, 0, 6, 6, 6, 6); + matrices.popPose(); + } else { + RenderSystem.setShaderTexture(0, InternalTextures.ARROW_LEFT_TEXTURE); + blit(matrices, tabLeftBounds.x + 4, tabLeftBounds.y + 4, 0, 0, 8, 8, 8, 8); + RenderSystem.setShaderTexture(0, InternalTextures.ARROW_RIGHT_TEXTURE); + blit(matrices, tabRightBounds.x + 4, tabRightBounds.y + 4, 0, 0, 8, 8, 8, 8); + } + }), 0, 0, 1)); + } + this.widgets.add(new Widget() { @Override public void render(PoseStack poses, int mouseX, int mouseY, float delta) { scrollAnimator.update(delta); int absLeft = bounds.x + bounds.width / 2 - tabsPerPage() * tabSize / 2; + int absRight = bounds.x + bounds.width / 2 + tabsPerPage() * tabSize / 2; int left; if (categories.size() > tabsPerPage()) { - left = bounds.x + bounds.width / 2 - tabSize / 2 - (int) Math.round(scrollAnimator.doubleValue()); + left = bounds.x + bounds.width / 2 - Math.min(categories.size(), tabsPerPage()) * tabSize / 2 - (int) Math.round(scrollAnimator.doubleValue()); updateScroll(categories, selectedCategory.getAsInt(), 300); } else { left = bounds.x + bounds.width / 2 - categories.size() * tabSize / 2; } - int passed = 0; for (TabWidget tab : Widgets.<TabWidget>walk(TabContainerWidget.this.widgets(), widget -> widget instanceof TabWidget)) { - if (categories.size() <= tabsPerPage()) { - tab.getBounds().x = left; - left += tabSize; - } else { - if (left > bounds.getMaxX()) { - while (left > bounds.getMaxX()) { - left -= tabSize * categories.size(); - } - tab.getBounds().x = left; - left += tabSize; - } else if (left + tabSize < bounds.x) { - while (left + tabSize < bounds.x) { - left += tabSize * categories.size(); - } - tab.getBounds().x = left; - left += tabSize; - } else { - tab.getBounds().x = left; - left += tabSize; - } - } - passed++; - - if (tab.getBounds().x > bounds.getMaxX() || tab.getBounds().getMaxX() < bounds.x) { - tab.getBounds().x = -1000; - } + tab.getBounds().x = left; + left += tabSize; - if (tab.getBounds().getCenterX() <= absLeft + 20) { - tab.opacity = 1 - (absLeft + 20 - tab.getBounds().getCenterX()) / 20f; - tab.opacity = (float) Math.pow(Mth.clamp(tab.opacity, 0, 1), 0.9); - } else if (tab.getBounds().getCenterX() >= absLeft + tabsPerPage() * tabSize - 20) { - tab.opacity = 1 - (tab.getBounds().getCenterX() - (absLeft + tabsPerPage() * tabSize - 20)) / 20f; - tab.opacity = (float) Math.pow(Mth.clamp(tab.opacity, 0, 1), 0.9); + if (tab.isSelected()) { + tab.opacity = 1; + } else if (tab.getBounds().getCenterX() <= absLeft) { + tab.opacity = 1 - (absLeft - tab.getBounds().getCenterX()) / 20f; + tab.opacity = (float) Math.pow(Mth.clamp(tab.opacity, 0, 1), 1.2); + } else if (tab.getBounds().getCenterX() >= absRight) { + tab.opacity = 1 - (tab.getBounds().getCenterX() - absRight) / 20f; + tab.opacity = (float) Math.pow(Mth.clamp(tab.opacity, 0, 1), 1.2); } else { tab.opacity = 1; } @@ -136,6 +171,11 @@ public class TabContainerWidget extends GuiComponent { if (tab.opacity < 0.1) { tab.opacity = 0; } + + if (tab.opacity == 0 || tab.getBounds().x > bounds.getMaxX() || tab.getBounds().getMaxX() < bounds.x) { + tab.getBounds().x = -1000; + tab.opacity = 0; + } } } @@ -184,7 +224,7 @@ public class TabContainerWidget extends GuiComponent { this.widgets.add(new DelegateWidget(tab) { @Override public void render(PoseStack poseStack, int mouseX, int mouseY, float delta) { - try (CloseableScissors scissors = Widget.scissor(poseStack, new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height + 4))) { + try (CloseableScissors scissors = Widget.scissor(poseStack, new Rectangle(scissorsBounds.x, scissorsBounds.y, scissorsBounds.width, scissorsBounds.height + 4))) { super.render(poseStack, mouseX, mouseY, delta); } } @@ -199,4 +239,12 @@ public class TabContainerWidget extends GuiComponent { public int tabsPerPage() { return tabsPerPage; } + + public int tabButtonsSize() { + return tabButtonsSize; + } + + public int tabSize() { + return tabSize; + } } |
