From caa850ff55576c8aef92c28ab5dcf87a319f6e3a Mon Sep 17 00:00:00 2001 From: shedaniel Date: Wed, 9 Feb 2022 20:17:34 +0800 Subject: Migrate to Cloth Config's ValueAnimator, and add option to cache entry renders --- .../shedaniel/rei/impl/client/REIRuntimeImpl.java | 2 + .../rei/impl/client/config/ConfigObjectImpl.java | 11 ++ .../client/config/entries/FilteringScreen.java | 28 ++-- .../rei/impl/client/gui/ScreenOverlayImpl.java | 5 + .../client/gui/dragging/CurrentDraggingStack.java | 4 +- .../rei/impl/client/gui/modules/Menu.java | 6 +- .../entries/EntryStackSubsetsMenuEntry.java | 2 +- .../gui/screen/CompositeDisplayViewingScreen.java | 5 +- .../gui/screen/DefaultDisplayViewingScreen.java | 2 +- .../gui/screen/UncertainDisplayViewingScreen.java | 4 +- .../gui/widget/BatchedEntryRendererManager.java | 2 +- .../client/gui/widget/CachedEntryListRender.java | 176 +++++++++++++++++++++ .../impl/client/gui/widget/EntryListWidget.java | 65 ++++++-- .../client/gui/widget/EntryStacksRegionWidget.java | 26 ++- .../rei/impl/client/gui/widget/EntryWidget.java | 4 +- .../client/gui/widget/FavoritesListWidget.java | 18 +-- .../rei/impl/client/gui/widget/TabWidget.java | 4 +- .../client/gui/widget/basewidgets/ArrowWidget.java | 4 +- .../gui/widget/basewidgets/BurningFireWidget.java | 4 +- .../gui/widget/basewidgets/ButtonWidget.java | 2 +- .../client/gui/widget/basewidgets/LabelWidget.java | 4 +- .../client/gui/widget/basewidgets/PanelWidget.java | 4 +- .../client/gui/widget/region/RealRegionEntry.java | 4 +- .../gui/widget/search/OverlaySearchField.java | 4 +- .../rei/impl/common/entry/AbstractEntryStack.java | 11 +- 25 files changed, 311 insertions(+), 90 deletions(-) create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/CachedEntryListRender.java (limited to 'runtime/src/main/java/me') diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java index 9351303cb..d5a6ddf94 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/REIRuntimeImpl.java @@ -43,6 +43,7 @@ import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry; import me.shedaniel.rei.api.common.registry.ReloadStage; import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl; import me.shedaniel.rei.impl.client.gui.hints.HintProvider; +import me.shedaniel.rei.impl.client.gui.widget.CachedEntryListRender; import me.shedaniel.rei.impl.client.gui.widget.search.OverlaySearchField; import me.shedaniel.rei.impl.client.search.argument.Argument; import net.fabricmc.api.EnvType; @@ -240,6 +241,7 @@ public class REIRuntimeImpl implements REIRuntime { Argument.SEARCH_CACHE.clear(); getOverlay().ifPresent(ScreenOverlay::queueReloadOverlay); lastDisplayScreen.clear(); + CachedEntryListRender.refresh(); } @Override 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 4fe37ff72..e79aecaa8 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 @@ -254,6 +254,15 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { return advanced.miscellaneous.newFastEntryRendering; } + @Override + public boolean doesCacheEntryRendering() { + return advanced.miscellaneous.cachingFastEntryRendering; + } + + public void setDoesCacheEntryRendering(boolean doesCacheEntryRendering) { + advanced.miscellaneous.cachingFastEntryRendering = doesCacheEntryRendering; + } + @Override public boolean doDebugRenderTimeRequired() { return advanced.layout.debugRenderTimeRequired; @@ -622,6 +631,8 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { @Comment("Declares whether arrows in containers should be clickable.") private boolean clickableRecipeArrows = true; private boolean registerRecipesInAnotherThread = true; private boolean newFastEntryRendering = true; + @ConfigEntry.Gui.PrefixText + private boolean cachingFastEntryRendering = false; } public static class Filtering { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringScreen.java index 2ea8b127a..5fcd5790e 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringScreen.java @@ -30,8 +30,7 @@ import com.mojang.blaze3d.vertex.*; import com.mojang.math.Matrix4f; import me.shedaniel.clothconfig2.ClothConfigInitializer; import me.shedaniel.clothconfig2.api.ScissorsHandler; -import me.shedaniel.clothconfig2.api.ScrollingContainer; -import me.shedaniel.clothconfig2.gui.widget.DynamicNewSmoothScrollingEntryListWidget; +import me.shedaniel.clothconfig2.api.scroll.ScrollingContainer; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.math.impl.PointHelper; @@ -80,7 +79,7 @@ public class FilteringScreen extends Screen { } @Override - public int getScrollBarX() { + public int getScrollBarX(int maxX) { return width - 7; } }; @@ -130,7 +129,7 @@ public class FilteringScreen extends Screen { for (int i = 0; i < entryStacks.size(); i++) { EntryStack stack = entryStacks.get(i); EntryListEntry entry = entries.get(i); - entry.getBounds().y = (int) (entry.backupY - scrolling.scrollAmount); + entry.getBounds().y = entry.backupY - scrolling.scrollAmountInt(); if (entry.isSelected() && !entry.isFiltered()) { filteringEntry.configFiltered.add(stack); filteringEntry.edited = true; @@ -145,7 +144,7 @@ public class FilteringScreen extends Screen { for (int i = 0; i < entryStacks.size(); i++) { EntryStack stack = entryStacks.get(i); EntryListEntry entry = entries.get(i); - entry.getBounds().y = (int) (entry.backupY - scrolling.scrollAmount); + entry.getBounds().y = entry.backupY - scrolling.scrollAmountInt(); if (entry.isSelected() && filteringEntry.configFiltered.remove(stack)) { filteringEntry.edited = true; entry.dirty = true; @@ -219,14 +218,14 @@ public class FilteringScreen extends Screen { ScissorsHandler.INSTANCE.scissor(bounds); for (EntryListEntry entry : entries) entry.clearStacks(); - int skip = Math.max(0, Mth.floor(scrolling.scrollAmount / (float) entrySize())); + int skip = Math.max(0, Mth.floor(scrolling.scrollAmount() / (float) entrySize())); int nextIndex = skip * innerBounds.width / entrySize(); int i = nextIndex; BatchedEntryRendererManager manager = new BatchedEntryRendererManager(); for (; i < entryStacks.size(); i++) { EntryStack stack = entryStacks.get(i); EntryListEntry entry = entries.get(nextIndex); - entry.getBounds().y = (int) (entry.backupY - scrolling.scrollAmount); + entry.getBounds().y = entry.backupY - scrolling.scrollAmountInt(); if (entry.getBounds().y > bounds.getMaxY()) break; entry.entry(stack); @@ -281,13 +280,13 @@ public class FilteringScreen extends Screen { Point p = secondPoint; if (p == null) { p = PointHelper.ofMouse(); - p.translate(0, (int) scrolling.scrollAmount); + p.translate(0, scrolling.scrollAmountInt()); } int left = Math.min(p.x, selectionPoint.x); int top = Math.min(p.y, selectionPoint.y); int right = Math.max(p.x, selectionPoint.x); int bottom = Math.max(p.y, selectionPoint.y); - selectionCache = new Rectangle(left, (int) (top - scrolling.scrollAmount), right - left, bottom - top); + selectionCache = new Rectangle(left, top - scrolling.scrollAmountInt(), right - left, bottom - top); return; } selectionCache = new Rectangle(0, 0, 0, 0); @@ -301,13 +300,6 @@ public class FilteringScreen extends Screen { } private void updatePosition(float delta) { - if (ConfigObject.getInstance().doesSnapToRows() && scrolling.scrollTarget >= 0 && scrolling.scrollTarget <= scrolling.getMaxScroll()) { - double nearestRow = Math.round(scrolling.scrollTarget / (double) entrySize()) * (double) entrySize(); - if (!DynamicNewSmoothScrollingEntryListWidget.Precision.almostEquals(scrolling.scrollTarget, nearestRow, DynamicNewSmoothScrollingEntryListWidget.Precision.FLOAT_EPSILON)) - scrolling.scrollTarget += (nearestRow - scrolling.scrollTarget) * Math.min(delta / 2.0, 1.0); - else - scrolling.scrollTarget = nearestRow; - } scrolling.updatePosition(delta); } @@ -377,7 +369,7 @@ public class FilteringScreen extends Screen { return true; } if (int_1 == 0) { - this.selectionPoint = new Point(double_1, double_2 + scrolling.scrollAmount); + this.selectionPoint = new Point(double_1, double_2 + scrolling.scrollAmount()); this.secondPoint = null; return true; } @@ -388,7 +380,7 @@ public class FilteringScreen extends Screen { @Override public boolean mouseReleased(double mouseX, double mouseY, int button) { if (selectionPoint != null && button == 0 && secondPoint == null) { - this.secondPoint = new Point(mouseX, mouseY + scrolling.scrollAmount); + this.secondPoint = new Point(mouseX, mouseY + scrolling.scrollAmount()); if (secondPoint.equals(selectionPoint)) { secondPoint.translate(1, 1); } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java index ff1fa2a2d..067e8d32e 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java @@ -442,6 +442,11 @@ public class ScreenOverlayImpl extends ScreenOverlay { config::setEntryListWidgetScrolled ), new SeparatorMenuEntry(), + ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.caching_entry_rendering"), + config::doesCacheEntryRendering, + config::setDoesCacheEntryRendering + ), + new SeparatorMenuEntry(), ToggleMenuEntry.of(new TranslatableComponent("text.rei.config.menu.display.side_search_field"), () -> config.getSearchFieldLocation() != SearchFieldLocation.CENTER, bool -> config.setSearchFieldLocation(bool ? SearchFieldLocation.BOTTOM_SIDE : SearchFieldLocation.CENTER) diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java index 1e204dbb2..df2d8d452 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/dragging/CurrentDraggingStack.java @@ -24,13 +24,13 @@ package me.shedaniel.rei.impl.client.gui.dragging; import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.clothconfig2.api.animator.NumberAnimator; +import me.shedaniel.clothconfig2.api.animator.ValueAnimator; import me.shedaniel.math.FloatingRectangle; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.math.impl.PointHelper; import me.shedaniel.rei.RoughlyEnoughItemsCoreClient; -import me.shedaniel.rei.api.client.gui.animator.NumberAnimator; -import me.shedaniel.rei.api.client.gui.animator.ValueAnimator; import me.shedaniel.rei.api.client.gui.drag.*; import me.shedaniel.rei.api.client.gui.widgets.Widget; import me.shedaniel.rei.impl.client.gui.widget.LateRenderable; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/Menu.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/Menu.java index 15afb1a4b..490a22d2a 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/Menu.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/Menu.java @@ -29,7 +29,7 @@ import com.google.common.collect.Sets; import com.mojang.blaze3d.vertex.PoseStack; import me.shedaniel.clothconfig2.ClothConfigInitializer; import me.shedaniel.clothconfig2.api.ScissorsHandler; -import me.shedaniel.clothconfig2.api.ScrollingContainer; +import me.shedaniel.clothconfig2.api.scroll.ScrollingContainer; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.RoughlyEnoughItemsCore; @@ -244,7 +244,7 @@ public class Menu extends WidgetWithBounds implements LateRenderable { fill(matrices, innerBounds.x, innerBounds.y, innerBounds.getMaxX(), innerBounds.getMaxY(), -16777216); boolean contains = innerBounds.contains(mouseX, mouseY); MenuEntry focused = getFocused() instanceof MenuEntry menuEntry ? menuEntry : null; - int currentY = (int) (innerBounds.y - scrolling.scrollAmount); + int currentY = innerBounds.y - scrolling.scrollAmountInt(); for (MenuEntry child : children()) { boolean containsMouse = contains && mouseY >= currentY && mouseY < currentY + child.getEntryHeight(); if (containsMouse) { @@ -252,7 +252,7 @@ public class Menu extends WidgetWithBounds implements LateRenderable { } currentY += child.getEntryHeight(); } - currentY = (int) (innerBounds.y - scrolling.scrollAmount); + currentY = innerBounds.y - scrolling.scrollAmountInt(); ScissorsHandler.INSTANCE.scissor(scrolling.getScissorBounds()); for (MenuEntry child : children()) { boolean rendering = currentY + child.getEntryHeight() >= innerBounds.y && currentY <= innerBounds.getMaxY(); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/EntryStackSubsetsMenuEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/EntryStackSubsetsMenuEntry.java index 27919c5d1..d6029865f 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/EntryStackSubsetsMenuEntry.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/EntryStackSubsetsMenuEntry.java @@ -79,7 +79,7 @@ public class EntryStackSubsetsMenuEntry extends AbstractMenuEntry { REIRuntime.getInstance().queueTooltip(stack.getTooltip(new Point(mouseX, mouseY))); if (RoughlyEnoughItemsCoreClient.isLeftMousePressed && !clickedLast) { clickedLast = true; - if (!getParent().scrolling.draggingScrollBar) { + if (getParent().scrolling.getScissorBounds().contains(mouseX, mouseY)) { minecraft.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F)); List> filteredStacks = ConfigObject.getInstance().getFilteredStackProviders(); if (isFiltered()) { 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 f986f5e61..1102abca8 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 @@ -27,7 +27,7 @@ import com.google.common.collect.Lists; import com.mojang.blaze3d.vertex.PoseStack; import me.shedaniel.clothconfig2.ClothConfigInitializer; import me.shedaniel.clothconfig2.api.ScissorsHandler; -import me.shedaniel.clothconfig2.api.ScrollingContainer; +import me.shedaniel.clothconfig2.api.scroll.ScrollingContainer; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.math.impl.PointHelper; @@ -109,7 +109,6 @@ public class CompositeDisplayViewingScreen extends AbstractDisplayViewingScreen super.init(); boolean isCompactTabs = ConfigObject.getInstance().isUsingCompactTabs(); int tabSize = isCompactTabs ? 24 : 28; - scrolling.draggingScrollBar = false; this.children().clear(); this.widgets.clear(); this.buttonList.clear(); @@ -357,7 +356,7 @@ public class CompositeDisplayViewingScreen extends AbstractDisplayViewingScreen matrices.pushPose(); ScissorsHandler.INSTANCE.scissor(scrolling.getBounds()); for (Button button : buttonList) { - button.getBounds().y = scrollListBounds.y + 1 + yOffset - (int) scrolling.scrollAmount; + button.getBounds().y = scrollListBounds.y + 1 + yOffset - scrolling.scrollAmountInt(); if (button.getBounds().getMaxY() > scrollListBounds.getMinY() && button.getBounds().getMinY() < scrollListBounds.getMaxY()) { button.render(matrices, mouseX, mouseY, delta); } 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 e90637e2e..b5457e2ed 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 @@ -30,13 +30,13 @@ import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.math.Matrix4f; import me.shedaniel.clothconfig2.api.ModifierKeyCode; +import me.shedaniel.clothconfig2.api.animator.ValueAnimator; import me.shedaniel.math.Color; import me.shedaniel.math.Point; 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.animator.ValueAnimator; 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; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/UncertainDisplayViewingScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/UncertainDisplayViewingScreen.java index 7a363f315..e9c71f7cd 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/UncertainDisplayViewingScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/UncertainDisplayViewingScreen.java @@ -30,6 +30,8 @@ import com.mojang.math.Matrix4f; import dev.architectury.platform.Platform; import it.unimi.dsi.fastutil.booleans.BooleanConsumer; import me.shedaniel.clothconfig2.api.ScissorsHandler; +import me.shedaniel.clothconfig2.api.animator.NumberAnimator; +import me.shedaniel.clothconfig2.api.animator.ValueAnimator; import me.shedaniel.clothconfig2.gui.widget.DynamicNewSmoothScrollingEntryListWidget; import me.shedaniel.clothconfig2.impl.EasingMethod; import me.shedaniel.math.Point; @@ -40,8 +42,6 @@ import me.shedaniel.rei.api.client.ClientHelper; import me.shedaniel.rei.api.client.REIRuntime; import me.shedaniel.rei.api.client.config.ConfigManager; import me.shedaniel.rei.api.client.config.ConfigObject; -import me.shedaniel.rei.api.client.gui.animator.NumberAnimator; -import me.shedaniel.rei.api.client.gui.animator.ValueAnimator; import me.shedaniel.rei.api.client.gui.config.DisplayScreenType; import me.shedaniel.rei.api.client.gui.widgets.Button; import me.shedaniel.rei.api.client.gui.widgets.Widget; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchedEntryRendererManager.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchedEntryRendererManager.java index 4693b12c9..ff472a9be 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchedEntryRendererManager.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/BatchedEntryRendererManager.java @@ -212,7 +212,7 @@ public class BatchedEntryRendererManager { firstRenderer.endBatch(first, extraData[0], matrices, delta); } - private static void renderSlow(boolean debugTime, MutableInt size, MutableLong time, PoseStack matrices, int mouseX, int mouseY, float delta, Iterable entries) { + public static void renderSlow(boolean debugTime, MutableInt size, MutableLong time, PoseStack matrices, int mouseX, int mouseY, float delta, Iterable entries) { for (T entry : entries) { if (entry.getCurrentEntry().isEmpty()) continue; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/CachedEntryListRender.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/CachedEntryListRender.java new file mode 100644 index 000000000..65447b81b --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/CachedEntryListRender.java @@ -0,0 +1,176 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.impl.client.gui.widget; + +import com.mojang.blaze3d.pipeline.TextureTarget; +import com.mojang.blaze3d.platform.Lighting; +import com.mojang.blaze3d.platform.NativeImage; +import com.mojang.blaze3d.platform.Window; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Matrix4f; +import dev.architectury.registry.ReloadListenerRegistry; +import it.unimi.dsi.fastutil.longs.Long2LongMap; +import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.RoughlyEnoughItemsCore; +import me.shedaniel.rei.api.client.entry.renderer.EntryRenderer; +import me.shedaniel.rei.api.client.registry.entry.EntryRegistry; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes; +import me.shedaniel.rei.api.common.util.EntryStacks; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.PackType; +import net.minecraft.util.Unit; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class CachedEntryListRender { + public static final int RESOLUTION = 64; + public static DynamicTexture cachedTexture; + public static ResourceLocation cachedTextureLocation; + public static Long2LongMap hash = new Long2LongOpenHashMap(); + + public static class Sprite { + public final float u0; + public final float u1; + public final float v0; + public final float v1; + + public Sprite(float u0, float u1, float v0, float v1) { + this.u0 = u0; + this.u1 = u1; + this.v0 = v0; + this.v1 = v1; + } + } + + static { + ReloadListenerRegistry.register(PackType.CLIENT_RESOURCES, (barrier, resourceManager, preparationProfiler, reloadProfiler, preparationExecutor, reloadExecutor) -> { + return barrier.wait(Unit.INSTANCE).thenRunAsync(CachedEntryListRender::refresh, reloadExecutor); + }); + } + + public static void refresh() { + RoughlyEnoughItemsCore.LOGGER.info("Refreshing cached entry list texture..."); + if (cachedTextureLocation != null) { + Minecraft.getInstance().getTextureManager().release(cachedTextureLocation); + cachedTextureLocation = null; + } + if (cachedTexture != null) { + cachedTexture.close(); + cachedTexture = null; + } + hash = new Long2LongOpenHashMap(); + } + + @Nullable + public static Sprite get(EntryStack stack) { + if (stack.getType() == VanillaEntryTypes.ITEM) { + if (stack.getNullable(EntryStack.Settings.RENDERER) != null) { + return null; + } + + if (cachedTexture == null) { + prepare(); + } + + long hashExact = EntryStacks.hashExact(stack); + + long hashOrDefault = hash.getOrDefault(hashExact, -1L); + if (hashOrDefault != -1L) { + // unpack + int x = (int) (hashOrDefault >> 32); + int y = (int) (hashOrDefault & 0xFFFFFFFFL); + float width = cachedTexture.getPixels().getWidth(); + float height = cachedTexture.getPixels().getWidth(); + return new Sprite(x * RESOLUTION / width, (x + 1) * RESOLUTION / width, y * RESOLUTION / height, (y + 1) * RESOLUTION / height); + } + } + + return null; + } + + private static void prepare() { + int side = 4; + List> list = EntryRegistry.getInstance().getPreFilteredList(); + while (side * side < list.size()) { + side++; + } + + int width = side * RESOLUTION; + int height = side * RESOLUTION; + + RoughlyEnoughItemsCore.LOGGER.info("Preparing cached texture with size %sx%s for %sx%s entries", width, height, side, side); + + hash = new Long2LongOpenHashMap(list.size() + 10); + Minecraft minecraft = Minecraft.getInstance(); + Window window = minecraft.getWindow(); + TextureTarget target = new TextureTarget(width, height, true, false); + target.bindWrite(true); + Matrix4f projectionMatrix = Matrix4f.orthographic(0.0F, width, 0.0F, height, 1000.0F, 3000.0F); + RenderSystem.setProjectionMatrix(projectionMatrix); + PoseStack modelViewStack = RenderSystem.getModelViewStack(); + modelViewStack.pushPose(); + modelViewStack.setIdentity(); + modelViewStack.translate(0.0D, 0.0D, -2000.0D); + RenderSystem.applyModelViewMatrix(); + + Lighting.setupFor3DItems(); + PoseStack matrices = new PoseStack(); + Rectangle bounds = new Rectangle(); + + int index = 0; + for (EntryStack stack : list) { + int x = index % side; + int y = index / side; + bounds.setBounds(x * RESOLUTION, y * RESOLUTION, RESOLUTION, RESOLUTION); + ((EntryRenderer) stack.getDefinition().getRenderer()).render((EntryStack) stack, matrices, bounds, -1, -1, 0); + hash.put(EntryStacks.hashExact(stack), pack(x, y)); + index++; + } + + NativeImage nativeImage = new NativeImage(width, height, false); + RenderSystem.bindTexture(target.getColorTextureId()); + nativeImage.downloadTexture(0, false); + nativeImage.flipY(); + + cachedTexture = new DynamicTexture(nativeImage); + cachedTextureLocation = minecraft.getTextureManager().register("rei_cached_entries", cachedTexture); + + target.destroyBuffers(); + Minecraft.getInstance().levelRenderer.graphicsChanged(); + Minecraft.getInstance().getMainRenderTarget().bindWrite(true); + + modelViewStack.popPose(); + RenderSystem.applyModelViewMatrix(); + } + + private static long pack(int x, int y) { + return ((long) x << 32) | (y & 0xFFFFFFFFL); + } +} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java index f1239135e..01699eb16 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java @@ -26,13 +26,13 @@ package me.shedaniel.rei.impl.client.gui.widget; import com.google.common.base.Predicates; import com.google.common.base.Stopwatch; import com.google.common.collect.Lists; +import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.math.Matrix4f; import me.shedaniel.clothconfig2.ClothConfigInitializer; import me.shedaniel.clothconfig2.api.ScissorsHandler; -import me.shedaniel.clothconfig2.api.ScrollingContainer; -import me.shedaniel.clothconfig2.gui.widget.DynamicNewSmoothScrollingEntryListWidget; +import me.shedaniel.clothconfig2.api.scroll.ScrollingContainer; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.math.impl.PointHelper; @@ -41,6 +41,7 @@ import me.shedaniel.rei.api.client.ClientHelper; import me.shedaniel.rei.api.client.REIRuntime; import me.shedaniel.rei.api.client.config.ConfigManager; import me.shedaniel.rei.api.client.config.ConfigObject; +import me.shedaniel.rei.api.client.entry.renderer.EntryRenderer; import me.shedaniel.rei.api.client.gui.config.EntryPanelOrdering; import me.shedaniel.rei.api.client.gui.drag.DraggableStack; import me.shedaniel.rei.api.client.gui.drag.DraggableStackVisitorWidget; @@ -273,7 +274,7 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg if (ConfigObject.getInstance().isEntryListWidgetScrolled()) { ScissorsHandler.INSTANCE.scissor(bounds); - int skip = Math.max(0, Mth.floor(scrolling.scrollAmount / (float) entrySize())); + int skip = Math.max(0, Mth.floor(scrolling.scrollAmount() / (float) entrySize())); int nextIndex = skip * innerBounds.width / entrySize(); this.blockedCount = 0; BatchedEntryRendererManager helper = new BatchedEntryRendererManager(); @@ -283,7 +284,7 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg EntryListEntry entry = entries.get(cont); Rectangle entryBounds = entry.getBounds(); - entryBounds.y = (int) (entry.backupY - scrolling.scrollAmount); + entryBounds.y = entry.backupY - scrolling.scrollAmountInt(); if (entryBounds.y > this.bounds.getMaxY()) break; if (allStacks.size() <= i) break; if (notSteppingOnExclusionZones(entryBounds.x, entryBounds.y, entryBounds.width, entryBounds.height, innerBounds)) { @@ -309,7 +310,32 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg for (Widget widget : renders) { widget.render(matrices, mouseX, mouseY, delta); } - new BatchedEntryRendererManager(entries).render(debugTime, size, time, matrices, mouseX, mouseY, delta); + if (ConfigObject.getInstance().doesCacheEntryRendering()) { + for (EntryListEntry entry : entries) { + if (entry.our == null) { + CachedEntryListRender.Sprite sprite = CachedEntryListRender.get(entry.getCurrentEntry()); + if (sprite != null) { + entry.our = entry.getCurrentEntry().copy().setting(EntryStack.Settings.RENDERER, stack -> new EntryRenderer() { + @Override + public void render(EntryStack entry, PoseStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) { + RenderSystem.setShaderTexture(0, CachedEntryListRender.cachedTextureLocation); + innerBlit(matrices.last().pose(), bounds.x, bounds.getMaxX(), bounds.y, bounds.getMaxY(), getBlitOffset(), sprite.u0, sprite.u1, sprite.v0, sprite.v1); + } + + @Override + @Nullable + public Tooltip getTooltip(EntryStack entry, Point mouse) { + return stack.getDefinition().getRenderer().getTooltip(entry.cast(), mouse); + } + }); + } + } + } + + BatchedEntryRendererManager.renderSlow(debugTime, size, time, matrices, mouseX, mouseY, delta, entries); + } else { + new BatchedEntryRendererManager(entries).render(debugTime, size, time, matrices, mouseX, mouseY, delta); + } } if (debugTime) { @@ -373,13 +399,14 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg } private void updatePosition(float delta) { - if (ConfigObject.getInstance().doesSnapToRows() && scrolling.scrollTarget >= 0 && scrolling.scrollTarget <= scrolling.getMaxScroll()) { - double nearestRow = Math.round(scrolling.scrollTarget / (double) entrySize()) * (double) entrySize(); - if (!DynamicNewSmoothScrollingEntryListWidget.Precision.almostEquals(scrolling.scrollTarget, nearestRow, DynamicNewSmoothScrollingEntryListWidget.Precision.FLOAT_EPSILON)) - scrolling.scrollTarget += (nearestRow - scrolling.scrollTarget) * Math.min(delta / 2.0, 1.0); - else - scrolling.scrollTarget = nearestRow; - } + // TODO: Snap to rows +// if (ConfigObject.getInstance().doesSnapToRows() && scrolling.scrollTarget() >= 0 && scrolling.scrollTarget() <= scrolling.getMaxScroll()) { +// double nearestRow = Math.round(scrolling.scrollTarget() / (double) entrySize()) * (double) entrySize(); +// if (!DynamicNewSmoothScrollingEntryListWidget.Precision.almostEquals(scrolling.scrollTarget(), nearestRow, DynamicNewSmoothScrollingEntryListWidget.Precision.FLOAT_EPSILON)) +// scrolling.scrollTarget += (nearestRow - scrolling.scrollTarget()) * Math.min(delta / 2.0, 1.0); +// else +// scrolling.scrollTarget = nearestRow; +// } scrolling.updatePosition(delta); } @@ -554,7 +581,7 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg @Override public Stream> getEntries() { if (ConfigObject.getInstance().isEntryListWidgetScrolled()) { - int skip = Math.max(0, Mth.floor(scrolling.scrollAmount / (float) entrySize())); + int skip = Math.max(0, Mth.floor(scrolling.scrollAmount() / (float) entrySize())); int nextIndex = skip * innerBounds.width / entrySize(); return (Stream>) (Stream>) entries.stream() .skip(nextIndex) @@ -568,11 +595,23 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg private class EntryListEntry extends EntryListEntryWidget { private Display display; + private EntryStack our; private EntryListEntry(int x, int y, int entrySize) { super(new Point(x, y), entrySize); } + @Override + public EntryStack getCurrentEntry() { + if (our != null) { + if (CachedEntryListRender.cachedTextureLocation != null) { + return our; + } + } + + return super.getCurrentEntry(); + } + @Override public boolean containsMouse(double mouseX, double mouseY) { return super.containsMouse(mouseX, mouseY) && containsChecked(mouseX, mouseY, true); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryStacksRegionWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryStacksRegionWidget.java index 11c30f8a6..32f072d11 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryStacksRegionWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryStacksRegionWidget.java @@ -30,8 +30,7 @@ import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.objects.ObjectIterator; import me.shedaniel.clothconfig2.ClothConfigInitializer; import me.shedaniel.clothconfig2.api.ScissorsHandler; -import me.shedaniel.clothconfig2.api.ScrollingContainer; -import me.shedaniel.clothconfig2.gui.widget.DynamicNewSmoothScrollingEntryListWidget; +import me.shedaniel.clothconfig2.api.scroll.ScrollingContainer; import me.shedaniel.math.FloatingPoint; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; @@ -84,10 +83,10 @@ public class EntryStacksRegionWidget> extends WidgetWit } @Override - public int getScrollBarX() { + public int getScrollBarX(int maxX) { if (!ConfigObject.getInstance().isLeftHandSidePanel()) return bounds.x + 1; - return bounds.getMaxX() - 7; + return maxX - 7; } }; private final Int2ObjectMap> entries = new Int2ObjectLinkedOpenHashMap<>(); @@ -169,13 +168,6 @@ public class EntryStacksRegionWidget> extends WidgetWit } private void updatePosition(float delta) { - if (ConfigObject.getInstance().doesSnapToRows() && scrolling.scrollTarget >= 0 && scrolling.scrollTarget <= scrolling.getMaxScroll()) { - double nearestRow = Math.round(scrolling.scrollTarget / (double) entrySize()) * (double) entrySize(); - if (!DynamicNewSmoothScrollingEntryListWidget.Precision.almostEquals(scrolling.scrollTarget, nearestRow, DynamicNewSmoothScrollingEntryListWidget.Precision.FLOAT_EPSILON)) - scrolling.scrollTarget += (nearestRow - scrolling.scrollTarget) * Math.min(delta / 2.0, 1.0); - else - scrolling.scrollTarget = nearestRow; - } scrolling.updatePosition(delta); } @@ -332,7 +324,7 @@ public class EntryStacksRegionWidget> extends WidgetWit currentY++; } - if (notSteppingOnExclusionZones(xPos, yPos - (int) scrolling.scrollAmount, entrySize, entrySize, innerBounds)) { + if (notSteppingOnExclusionZones(xPos, yPos - scrolling.scrollAmountInt(), entrySize, entrySize, innerBounds)) { if (slotIndex++ == releaseIndex) { continue; } @@ -366,7 +358,7 @@ public class EntryStacksRegionWidget> extends WidgetWit currentY++; } - if (notSteppingOnExclusionZones(xPos, yPos - (int) scrolling.scrollAmount, entrySize, entrySize, innerBounds)) { + if (notSteppingOnExclusionZones(xPos, yPos - scrolling.scrollAmountInt(), entrySize, entrySize, innerBounds)) { entriesPoints.add(new Tuple<>(entry, new Point(xPos, yPos))); break; } else { @@ -380,13 +372,13 @@ public class EntryStacksRegionWidget> extends WidgetWit int xPos = currentX * entrySize + innerBounds.x; int yPos = currentY * entrySize + innerBounds.y; - if (notSteppingOnExclusionZones(xPos, yPos - (int) scrolling.scrollAmount, entrySize, entrySize, innerBounds)) { + if (notSteppingOnExclusionZones(xPos, yPos - scrolling.scrollAmountInt(), entrySize, entrySize, innerBounds)) { entriesPoints.add(new Tuple<>(null, new Point(xPos, yPos))); } } double x = position.x - 8; - double y = position.y + scrolling.scrollAmount - 8; + double y = position.y + scrolling.scrollAmount() - 8; return Mth.clamp(entriesPoints.stream() .filter(value -> { @@ -419,7 +411,7 @@ public class EntryStacksRegionWidget> extends WidgetWit public boolean drop(RealRegionEntry entry) { DraggingContext context = DraggingContext.getInstance(); double x = context.getCurrentPosition().x; - double y = context.getCurrentPosition().y + scrolling.scrollAmount; + double y = context.getCurrentPosition().y + scrolling.scrollAmount(); return drop(entry, x, y); } @@ -481,7 +473,7 @@ public class EntryStacksRegionWidget> extends WidgetWit } public double getScrollAmount() { - return scrolling.scrollAmount; + return scrolling.scrollAmount(); } public boolean has(RealRegionEntry entry) { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java index 2e47d12bd..a20825496 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java @@ -27,6 +27,8 @@ import com.mojang.blaze3d.platform.InputConstants; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import me.shedaniel.clothconfig2.api.ModifierKeyCode; +import me.shedaniel.clothconfig2.api.animator.NumberAnimator; +import me.shedaniel.clothconfig2.api.animator.ValueAnimator; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.math.impl.PointHelper; @@ -34,8 +36,6 @@ import me.shedaniel.rei.api.client.REIRuntime; import me.shedaniel.rei.api.client.config.ConfigManager; import me.shedaniel.rei.api.client.config.ConfigObject; import me.shedaniel.rei.api.client.favorites.FavoriteEntry; -import me.shedaniel.rei.api.client.gui.animator.NumberAnimator; -import me.shedaniel.rei.api.client.gui.animator.ValueAnimator; import me.shedaniel.rei.api.client.gui.drag.DraggableStack; import me.shedaniel.rei.api.client.gui.drag.DraggableStackProviderWidget; import me.shedaniel.rei.api.client.gui.drag.DraggedAcceptorResult; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java index 5894740da..a8f4d68d4 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java @@ -29,7 +29,10 @@ import com.mojang.blaze3d.vertex.Tesselator; import me.shedaniel.clothconfig2.ClothConfigInitializer; import me.shedaniel.clothconfig2.api.LazyResettable; import me.shedaniel.clothconfig2.api.ScissorsHandler; -import me.shedaniel.clothconfig2.api.ScrollingContainer; +import me.shedaniel.clothconfig2.api.animator.NumberAnimator; +import me.shedaniel.clothconfig2.api.animator.ProgressValueAnimator; +import me.shedaniel.clothconfig2.api.animator.ValueAnimator; +import me.shedaniel.clothconfig2.api.scroll.ScrollingContainer; import me.shedaniel.math.FloatingPoint; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; @@ -41,9 +44,6 @@ import me.shedaniel.rei.api.client.favorites.FavoriteEntry; import me.shedaniel.rei.api.client.favorites.FavoriteEntryType; import me.shedaniel.rei.api.client.favorites.SystemFavoriteEntryProvider; import me.shedaniel.rei.api.client.gui.AbstractContainerEventHandler; -import me.shedaniel.rei.api.client.gui.animator.NumberAnimator; -import me.shedaniel.rei.api.client.gui.animator.ProgressValueAnimator; -import me.shedaniel.rei.api.client.gui.animator.ValueAnimator; import me.shedaniel.rei.api.client.gui.drag.*; import me.shedaniel.rei.api.client.gui.widgets.Tooltip; import me.shedaniel.rei.api.client.gui.widgets.Widget; @@ -333,10 +333,8 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt DraggableStack currentStack = DraggingContext.getInstance().getCurrentStack(); if (currentStack instanceof RegionDraggableStack) { RegionDraggableStack stack = (RegionDraggableStack) currentStack; - - if (stack.getEntry().region == region && Objects.equals(stack.getEntry().getEntry(), entry)) { - return false; - } + + return stack.getEntry().region != region || !Objects.equals(stack.getEntry().getEntry(), entry); } } return true; @@ -562,7 +560,7 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt if (expendState.progress() > 0.1f) { ScissorsHandler.INSTANCE.scissor(scrollBounds); matrices.pushPose(); - matrices.translate(0, scroller.scrollAmount, 0); + matrices.translate(0, scroller.scrollAmount(), 0); int y = scrollBounds.y; for (Row row : rows.get()) { row.render(matrices, scrollBounds.x, y, scrollBounds.width, row.getRowHeight(), mouseX, mouseY, delta); @@ -753,7 +751,7 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt currentY++; } - if (notSteppingOnExclusionZones(xPos, yPos + lastY + (int) scroller.scrollAmount, entrySize, entrySize, scrollBounds)) { + if (notSteppingOnExclusionZones(xPos, yPos + lastY + scroller.scrollAmountInt(), entrySize, entrySize, scrollBounds)) { widget.moveTo(animated.test(widget), xPos, yPos); break; } else { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabWidget.java index 0f8b9211d..d192740af 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabWidget.java @@ -25,13 +25,13 @@ package me.shedaniel.rei.impl.client.gui.widget; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.clothconfig2.api.animator.NumberAnimator; +import me.shedaniel.clothconfig2.api.animator.ValueAnimator; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.ClientHelper; import me.shedaniel.rei.api.client.REIRuntime; import me.shedaniel.rei.api.client.gui.Renderer; -import me.shedaniel.rei.api.client.gui.animator.NumberAnimator; -import me.shedaniel.rei.api.client.gui.animator.ValueAnimator; import me.shedaniel.rei.api.client.gui.drag.DraggableStack; import me.shedaniel.rei.api.client.gui.drag.DraggableStackProviderWidget; import me.shedaniel.rei.api.client.gui.drag.DraggedAcceptorResult; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/ArrowWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/ArrowWidget.java index 51ac91524..5023437b0 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/ArrowWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/ArrowWidget.java @@ -25,10 +25,10 @@ package me.shedaniel.rei.impl.client.gui.widget.basewidgets; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; +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.REIRuntime; -import me.shedaniel.rei.api.client.gui.animator.NumberAnimator; -import me.shedaniel.rei.api.client.gui.animator.ValueAnimator; import me.shedaniel.rei.api.client.gui.widgets.Arrow; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.util.Mth; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/BurningFireWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/BurningFireWidget.java index 5f5053a34..788df5ee6 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/BurningFireWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/BurningFireWidget.java @@ -25,10 +25,10 @@ package me.shedaniel.rei.impl.client.gui.widget.basewidgets; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; +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.REIRuntime; -import me.shedaniel.rei.api.client.gui.animator.NumberAnimator; -import me.shedaniel.rei.api.client.gui.animator.ValueAnimator; import me.shedaniel.rei.api.client.gui.widgets.BurningFire; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.util.Mth; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/ButtonWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/ButtonWidget.java index 245f67178..3ed9e3016 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/ButtonWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/ButtonWidget.java @@ -26,11 +26,11 @@ package me.shedaniel.rei.impl.client.gui.widget.basewidgets; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Matrix4f; +import me.shedaniel.clothconfig2.api.animator.ValueAnimator; import me.shedaniel.math.Color; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.REIRuntime; -import me.shedaniel.rei.api.client.gui.animator.ValueAnimator; import me.shedaniel.rei.api.client.gui.widgets.Button; import me.shedaniel.rei.api.client.gui.widgets.Tooltip; import net.minecraft.client.gui.GuiComponent; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/LabelWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/LabelWidget.java index 2bd025c72..f81f98165 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/LabelWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/LabelWidget.java @@ -25,12 +25,12 @@ package me.shedaniel.rei.impl.client.gui.widget.basewidgets; import com.mojang.blaze3d.vertex.PoseStack; import me.shedaniel.clothconfig2.api.LazyResettable; +import me.shedaniel.clothconfig2.api.animator.ValueAnimator; +import me.shedaniel.clothconfig2.api.animator.ValueProvider; import me.shedaniel.math.Color; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.REIRuntime; -import me.shedaniel.rei.api.client.gui.animator.ValueAnimator; -import me.shedaniel.rei.api.client.gui.animator.ValueProvider; import me.shedaniel.rei.api.client.gui.widgets.Label; import me.shedaniel.rei.api.client.gui.widgets.Tooltip; import me.shedaniel.rei.api.client.gui.widgets.Widgets; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/PanelWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/PanelWidget.java index 26f4480b5..3e838ec15 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/PanelWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/basewidgets/PanelWidget.java @@ -27,11 +27,11 @@ import com.google.common.base.Predicates; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Matrix4f; +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.REIRuntime; import me.shedaniel.rei.api.client.config.ConfigObject; -import me.shedaniel.rei.api.client.gui.animator.NumberAnimator; -import me.shedaniel.rei.api.client.gui.animator.ValueAnimator; import me.shedaniel.rei.api.client.gui.config.DisplayScreenType; import me.shedaniel.rei.api.client.gui.config.RecipeBorderType; import me.shedaniel.rei.api.client.gui.widgets.Panel; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/RealRegionEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/RealRegionEntry.java index c1a749c3a..3cea6ed1d 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/RealRegionEntry.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/RealRegionEntry.java @@ -23,11 +23,11 @@ package me.shedaniel.rei.impl.client.gui.widget.region; +import me.shedaniel.clothconfig2.api.animator.NumberAnimator; +import me.shedaniel.clothconfig2.api.animator.ValueAnimator; import me.shedaniel.math.FloatingPoint; import me.shedaniel.rei.api.client.config.ConfigObject; import me.shedaniel.rei.api.client.entry.region.RegionEntry; -import me.shedaniel.rei.api.client.gui.animator.NumberAnimator; -import me.shedaniel.rei.api.client.gui.animator.ValueAnimator; import me.shedaniel.rei.impl.client.gui.widget.EntryStacksRegionWidget; import static me.shedaniel.rei.impl.client.gui.widget.EntryListWidget.entrySize; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/OverlaySearchField.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/OverlaySearchField.java index df4b4409e..951427173 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/OverlaySearchField.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/OverlaySearchField.java @@ -29,14 +29,14 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.*; import com.mojang.datafixers.util.Pair; import com.mojang.math.Matrix4f; +import me.shedaniel.clothconfig2.api.animator.NumberAnimator; +import me.shedaniel.clothconfig2.api.animator.ValueAnimator; import me.shedaniel.math.Color; import me.shedaniel.math.Point; 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.animator.NumberAnimator; -import me.shedaniel.rei.api.client.gui.animator.ValueAnimator; import me.shedaniel.rei.api.client.gui.config.SyntaxHighlightingMode; import me.shedaniel.rei.api.client.gui.widgets.Tooltip; import me.shedaniel.rei.api.common.util.CollectionUtils; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/AbstractEntryStack.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/AbstractEntryStack.java index b8de9d7ca..3ffd5a2df 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/AbstractEntryStack.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/AbstractEntryStack.java @@ -182,14 +182,21 @@ public abstract class AbstractEntryStack implements EntryStack, Renderer { @Override public T get(Settings settings) { - T o = this.settings == null ? null : (T) this.settings.get(settings.getId()); - o = EntrySettingsAdapterRegistry.getInstance().adapt(this, settings, o); + T o = getNullable(settings); if (o == null) { o = settings.getDefaultValue(); } return o; } + @Override + @Nullable + public T getNullable(Settings settings) { + T o = this.settings == null ? null : (T) this.settings.get(settings.getId()); + o = EntrySettingsAdapterRegistry.getInstance().adapt(this, settings, o); + return o; + } + @Override public void render(PoseStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) { try { -- cgit From a0162fe0f6f73bc2dbfdee29ae2e32a06b5e13a7 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Wed, 9 Feb 2022 21:21:30 +0800 Subject: Close #757 --- .../rei/impl/client/config/ConfigObjectImpl.java | 7 ++++ .../client/gui/widget/FavoritesListWidget.java | 47 ++++++++++++++++++---- 2 files changed, 47 insertions(+), 7 deletions(-) (limited to 'runtime/src/main/java/me') 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 e79aecaa8..c05d7f8a8 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 @@ -273,6 +273,11 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { return advanced.layout.mergeDisplayUnderOne; } + @Override + public FavoriteAddWidgetMode getFavoriteAddWidgetMode() { + return advanced.layout.favoriteAddWidgetMode; + } + @Override public ModifierKeyCode getFavoriteKeyCode() { return basics.keyBindings.favoriteKeybind == null ? ModifierKeyCode.unknown() : basics.keyBindings.favoriteKeybind; @@ -594,6 +599,8 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { private int maxRecipesPageHeight = 300; @Comment("Declares whether entry rendering time should be debugged.") private boolean debugRenderTimeRequired = false; @Comment("Merges displays with equal contents under 1 display.") private boolean mergeDisplayUnderOne = true; + @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON) + private FavoriteAddWidgetMode favoriteAddWidgetMode = FavoriteAddWidgetMode.ALWAYS_VISIBLE; } public static class Accessibility { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java index a8f4d68d4..f06cd8f20 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java @@ -333,7 +333,7 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt DraggableStack currentStack = DraggingContext.getInstance().getCurrentStack(); if (currentStack instanceof RegionDraggableStack) { RegionDraggableStack stack = (RegionDraggableStack) currentStack; - + return stack.getEntry().region != region || !Objects.equals(stack.getEntry().getEntry(), entry); } } @@ -451,7 +451,17 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { this.bounds.setBounds(updateArea(widget.fullBounds)); boolean hovered = containsMouse(mouseX, mouseY); - this.alpha.setTo(hovered ? 1f : isAvailable(mouseX, mouseY) ? 0.3f : 0f, 260); + switch (ConfigObject.getInstance().getFavoriteAddWidgetMode()) { + case ALWAYS_INVISIBLE: + this.alpha.setAs(0); + break; + case AUTO_HIDE: + this.alpha.setTo(hovered ? 1f : isAvailable(mouseX, mouseY) ? 0.5f : 0f, 260); + break; + case ALWAYS_VISIBLE: + this.alpha.setAs(hovered ? 1f : 0.5f); + break; + } this.alpha.update(delta); int buttonColor = 0xFFFFFF | (Math.round(0x74 * alpha.floatValue()) << 24); fillGradient(matrices, bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), buttonColor, buttonColor); @@ -526,6 +536,7 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt rows.add(new SectionSeparatorRow()); } if (!rows.isEmpty()) rows.remove(rows.size() - 1); + rows.add(new EmptySectionRow(4)); return rows; }); private final ScrollingContainer scroller = new ScrollingContainer() { @@ -557,10 +568,10 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt fillGradient(matrices, bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), buttonColor, buttonColor); scroller.updatePosition(delta); - if (expendState.progress() > 0.1f) { + if (expendState.value()) { ScissorsHandler.INSTANCE.scissor(scrollBounds); matrices.pushPose(); - matrices.translate(0, scroller.scrollAmount(), 0); + matrices.translate(0, -scroller.scrollAmount(), 0); int y = scrollBounds.y; for (Row row : rows.get()) { row.render(matrices, scrollBounds.x, y, scrollBounds.width, row.getRowHeight(), mouseX, mouseY, delta); @@ -573,14 +584,14 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt private Rectangle updatePanelArea(Rectangle fullArea) { int currentWidth = 16 + Math.round(Math.min((float) expendState.progress(), 1) * (fullArea.getWidth() - 16 - 8)); - int currentHeight = 16 + Math.round((float) expendState.progress() * (fullArea.getHeight() * 0.4f - 16 - 8)); + int currentHeight = 16 + Math.round((float) expendState.progress() * (fullArea.getHeight() * 0.4f - 16 - 8 + 4)); return new Rectangle(fullArea.x + 4, fullArea.getMaxY() - currentHeight - 4, currentWidth, currentHeight); } @Override public boolean mouseScrolled(double d, double