diff options
| author | shedaniel <daniel@shedaniel.me> | 2022-04-14 12:50:23 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2022-04-15 13:19:08 +0800 |
| commit | dba99e00520cc44225dd6310eb9272ddf2f6611f (patch) | |
| tree | 87c58ef2bd76ba321369a6ad7b39c7ab1efa342b /runtime/src/main/java | |
| parent | cf48c7f4b8c98296300552e6f67b2f13c21cfcec (diff) | |
| download | RoughlyEnoughItems-dba99e00520cc44225dd6310eb9272ddf2f6611f.tar.gz RoughlyEnoughItems-dba99e00520cc44225dd6310eb9272ddf2f6611f.tar.bz2 RoughlyEnoughItems-dba99e00520cc44225dd6310eb9272ddf2f6611f.zip | |
Add what's getting hidden in the search filtering screen
Diffstat (limited to 'runtime/src/main/java')
2 files changed, 198 insertions, 7 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRuleOptionsScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRuleOptionsScreen.java index 154c34445..fac731ecf 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRuleOptionsScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRuleOptionsScreen.java @@ -23,8 +23,12 @@ package me.shedaniel.rei.impl.client.config.entries; +import com.google.common.collect.Collections2; +import com.google.common.collect.Lists; +import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import me.shedaniel.clothconfig2.gui.widget.DynamicElementListWidget; +import me.shedaniel.math.Rectangle; import me.shedaniel.rei.impl.client.entry.filtering.FilteringRule; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.Button; @@ -32,16 +36,21 @@ import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.narration.NarratableEntry; import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.resources.sounds.SimpleSoundInstance; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.FormattedText; import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundEvents; import net.minecraft.util.FormattedCharSequence; +import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; public abstract class FilteringRuleOptionsScreen<T extends FilteringRule<?>> extends Screen { private final FilteringEntry entry; @@ -258,4 +267,117 @@ public abstract class FilteringRuleOptionsScreen<T extends FilteringRule<?>> ext return Collections.singletonList(widget); } } + + public static class SubRulesEntry extends RuleEntry { + private static final ResourceLocation CONFIG_TEX = new ResourceLocation("cloth-config2", "textures/gui/cloth_config.png"); + private final CategoryLabelWidget widget; + private final List<RuleEntry> rules; + private final List<GuiEventListener> children; + private boolean expanded; + private Supplier<Component> name; + + public SubRulesEntry(FilteringRule<?> rule, Supplier<Component> name, List<RuleEntry> rules) { + super(rule); + this.rules = rules; + this.widget = new CategoryLabelWidget(); + this.name = name; + this.expanded = true; + this.children = new ArrayList<>(rules); + this.children.add(widget); + } + + public List<RuleEntry> getRules() { + return rules; + } + + @Override + public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) { + RenderSystem.setShaderTexture(0, CONFIG_TEX); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + this.widget.rectangle.x = x + 3; + this.widget.rectangle.y = y; + this.widget.rectangle.width = entryWidth - 6; + this.widget.rectangle.height = 24; + this.blit(matrices, x + 3, y + 5, 24, (this.widget.rectangle.contains(mouseX, mouseY) ? 18 : 0) + (this.expanded ? 9 : 0), 9, 9); + Minecraft.getInstance().font.drawShadow(matrices, this.name.get().getVisualOrderText(), (float) x + 3 + 15, (float) (y + 6), this.widget.rectangle.contains(mouseX, mouseY) ? -1638890 : -1); + + for (RuleEntry performanceEntry : this.rules) { + performanceEntry.setParent(this.getParent()); + } + + if (this.expanded) { + int yy = y + 24; + + RuleEntry entry; + for (Iterator<RuleEntry> iterator = this.rules.iterator(); iterator.hasNext(); yy += entry.getItemHeight()) { + entry = iterator.next(); + entry.render(matrices, -1, yy, x + 3 + 15, entryWidth - 15 - 3, entry.getItemHeight(), mouseX, mouseY, isHovered && this.getFocused() == entry, delta); + } + } + } + + @Override + public int getMorePossibleHeight() { + if (!this.expanded) { + return -1; + } else { + List<Integer> list = new ArrayList<>(); + int i = 24; + + for (RuleEntry entry : this.rules) { + i += entry.getItemHeight(); + if (entry.getMorePossibleHeight() >= 0) { + list.add(i + entry.getMorePossibleHeight()); + } + } + + list.add(i); + return list.stream().max(Integer::compare).orElse(0) - this.getItemHeight(); + } + } + + @Override + public int getItemHeight() { + if (!this.expanded) { + return 24; + } else { + int i = 24; + + RuleEntry entry; + for (Iterator<RuleEntry> iterator = this.rules.iterator(); iterator.hasNext(); i += entry.getItemHeight()) { + entry = iterator.next(); + } + + return i; + } + } + + @Override + public List<? extends GuiEventListener> children() { + return children; + } + + @Override + public List<? extends NarratableEntry> narratables() { + return Collections.emptyList(); + } + + public class CategoryLabelWidget implements GuiEventListener { + private final Rectangle rectangle = new Rectangle(); + + public CategoryLabelWidget() { + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (this.rectangle.contains(mouseX, mouseY)) { + SubRulesEntry.this.expanded = !SubRulesEntry.this.expanded; + Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F)); + return true; + } else { + return false; + } + } + } + } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java index 5f5969674..0e48f1b97 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java @@ -25,35 +25,49 @@ package me.shedaniel.rei.impl.client.entry.filtering.rules; import com.google.common.base.Suppliers; import com.google.common.collect.Lists; +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.clothconfig2.api.ScissorsHandler; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.REIRuntime; +import me.shedaniel.rei.api.client.registry.entry.EntryRegistry; import me.shedaniel.rei.api.client.search.SearchFilter; import me.shedaniel.rei.api.client.search.SearchProvider; import me.shedaniel.rei.api.common.entry.EntryStack; import me.shedaniel.rei.api.common.util.CollectionUtils; import me.shedaniel.rei.impl.client.config.entries.FilteringEntry; import me.shedaniel.rei.impl.client.config.entries.FilteringRuleOptionsScreen; +import me.shedaniel.rei.impl.client.config.entries.FilteringScreen; import me.shedaniel.rei.impl.client.entry.filtering.AbstractFilteringRule; import me.shedaniel.rei.impl.client.entry.filtering.FilteringCache; import me.shedaniel.rei.impl.client.entry.filtering.FilteringContext; import me.shedaniel.rei.impl.client.entry.filtering.FilteringResult; +import me.shedaniel.rei.impl.client.gui.widget.BatchedEntryRendererManager; +import me.shedaniel.rei.impl.client.gui.widget.EntryWidget; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.narration.NarratableEntry; import net.minecraft.client.gui.screens.Screen; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.util.Mth; import net.minecraft.util.StringUtil; -import java.util.Collection; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.BiFunction; import java.util.function.Consumer; +import java.util.function.Function; import java.util.function.Supplier; +import java.util.stream.Collectors; + +import static me.shedaniel.rei.impl.client.gui.widget.EntryListWidget.entrySize; @Environment(EnvType.CLIENT) public class SearchFilteringRule extends AbstractFilteringRule<SearchFilteringRule> { @@ -115,7 +129,7 @@ public class SearchFilteringRule extends AbstractFilteringRule<SearchFilteringRu @Override public SearchFilteringRule createNew() { - return new SearchFilteringRule("", true); + return new SearchFilteringRule("", false); } private void processList(Collection<EntryStack<?>> stacks, List<CompletableFuture<List<EntryStack<?>>>> completableFutures) { @@ -147,21 +161,34 @@ public class SearchFilteringRule extends AbstractFilteringRule<SearchFilteringRu return Optional.of((entry, screen) -> new FilteringRuleOptionsScreen<SearchFilteringRule>(entry, this, screen) { TextFieldRuleEntry entry = null; BooleanRuleEntry show = null; - + List<EntryWidget> entryStacks = new ArrayList<>(); + @Override public void addEntries(Consumer<RuleEntry> entryConsumer) { addEmpty(entryConsumer, 10); addText(entryConsumer, new TranslatableComponent("rule.roughlyenoughitems.filtering.search.filter").withStyle(ChatFormatting.GRAY)); entryConsumer.accept(entry = new TextFieldRuleEntry(width - 36, rule, widget -> { widget.setMaxLength(9999); + widget.setResponder(searchTerm -> { + SearchFilter filter = SearchProvider.getInstance().createFilter(searchTerm); + entryStacks = EntryRegistry.getInstance().getEntryStacks().parallel() + .filter(filter) + .map(EntryStack::normalize) + .map(stack -> new EntryWidget(new Rectangle(0, 0, 18,18)).noBackground().entry(stack)) + .collect(Collectors.toList()); + }); if (entry != null) widget.setValue(entry.getWidget().getValue()); else widget.setValue(rule.filterStr); })); addEmpty(entryConsumer, 10); addText(entryConsumer, new TranslatableComponent("rule.roughlyenoughitems.filtering.search.show").withStyle(ChatFormatting.GRAY)); - entryConsumer.accept(show = new BooleanRuleEntry(width - 36, show == null ? rule.show : show.getBoolean(), rule, bool -> { + Function<Boolean, Component> function = bool -> { return new TranslatableComponent("rule.roughlyenoughitems.filtering.search.show." + bool); - })); + }; + entryConsumer.accept(show = new BooleanRuleEntry(width - 36, show == null ? rule.show : show.getBoolean(), rule, function)); + addEmpty(entryConsumer, 10); + entryConsumer.accept(new SubRulesEntry(rule, () -> function.apply(show == null ? rule.show : show.getBoolean()), + Collections.singletonList(new EntryStacksRuleEntry(rule, () -> entryStacks, entry, show)))); } @Override @@ -171,4 +198,46 @@ public class SearchFilteringRule extends AbstractFilteringRule<SearchFilteringRu } }); } + + public static class EntryStacksRuleEntry extends FilteringRuleOptionsScreen.RuleEntry { + private final Supplier<List<EntryWidget>> entryStacks; + private int totalHeight; + + public EntryStacksRuleEntry(SearchFilteringRule rule, Supplier<List<EntryWidget>> entryStacks, FilteringRuleOptionsScreen.TextFieldRuleEntry entry, FilteringRuleOptionsScreen.BooleanRuleEntry show) { + super(rule); + this.entryStacks = entryStacks; + } + + @Override + public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) { + BatchedEntryRendererManager manager = new BatchedEntryRendererManager(); + int entrySize = entrySize(); + int width = entryWidth / entrySize; + int i = 0; + for (EntryWidget stack : entryStacks.get()) { + stack.getBounds().setLocation(x + (i % width) * entrySize, y + (i / width) * entrySize); + if (stack.getBounds().getMaxY() >= 0 && stack.getBounds().getY() <= Minecraft.getInstance().getWindow().getGuiScaledHeight()) { + manager.add(stack); + } + i++; + } + manager.render(matrices, mouseX, mouseY, delta); + totalHeight = (i / width + 1) * entrySize; + } + + @Override + public int getItemHeight() { + return totalHeight; + } + + @Override + public List<? extends NarratableEntry> narratables() { + return Lists.newArrayList(); + } + + @Override + public List<? extends GuiEventListener> children() { + return Lists.newArrayList(); + } + } } |
