diff options
| author | shedaniel <daniel@shedaniel.me> | 2020-07-08 22:49:27 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2020-07-08 22:49:27 +0800 |
| commit | ddbedf6a7dc89176ab7797e5aaa10d6ea563f9a9 (patch) | |
| tree | 3ecdb75f9c34c5cba27c15ee84d845aaa654eb2e /src/main/java/me | |
| parent | 1189bcf3a46777239462da0dc45aa088697fec40 (diff) | |
| download | RoughlyEnoughItems-ddbedf6a7dc89176ab7797e5aaa10d6ea563f9a9.tar.gz RoughlyEnoughItems-ddbedf6a7dc89176ab7797e5aaa10d6ea563f9a9.tar.bz2 RoughlyEnoughItems-ddbedf6a7dc89176ab7797e5aaa10d6ea563f9a9.zip | |
Custom Filtering Rules
Signed-off-by: shedaniel <daniel@shedaniel.me>
Diffstat (limited to 'src/main/java/me')
23 files changed, 1445 insertions, 27 deletions
diff --git a/src/main/java/me/shedaniel/rei/api/ConfigObject.java b/src/main/java/me/shedaniel/rei/api/ConfigObject.java index a581ce649..4f4a3ff3f 100644 --- a/src/main/java/me/shedaniel/rei/api/ConfigObject.java +++ b/src/main/java/me/shedaniel/rei/api/ConfigObject.java @@ -26,6 +26,7 @@ package me.shedaniel.rei.api; import me.shedaniel.clothconfig2.api.ModifierKeyCode; import me.shedaniel.rei.gui.config.*; import me.shedaniel.rei.impl.ConfigManagerImpl; +import me.shedaniel.rei.impl.filtering.FilteringRule; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import org.jetbrains.annotations.ApiStatus; @@ -150,6 +151,8 @@ public interface ConfigObject { List<EntryStack> getFilteredStacks(); + List<FilteringRule<?>> getFilteringRules(); + @ApiStatus.Experimental boolean shouldAsyncSearch(); diff --git a/src/main/java/me/shedaniel/rei/api/EntryRegistry.java b/src/main/java/me/shedaniel/rei/api/EntryRegistry.java index 80f25cbf6..56c9aac19 100644 --- a/src/main/java/me/shedaniel/rei/api/EntryRegistry.java +++ b/src/main/java/me/shedaniel/rei/api/EntryRegistry.java @@ -25,6 +25,8 @@ package me.shedaniel.rei.api; import me.shedaniel.rei.RoughlyEnoughItemsCore; import me.shedaniel.rei.utils.CollectionUtils; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import org.jetbrains.annotations.ApiStatus; @@ -33,6 +35,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; +@Environment(EnvType.CLIENT) public interface EntryRegistry { /** diff --git a/src/main/java/me/shedaniel/rei/gui/config/entry/FilteringAddRuleScreen.java b/src/main/java/me/shedaniel/rei/gui/config/entry/FilteringAddRuleScreen.java new file mode 100644 index 000000000..cfcb02396 --- /dev/null +++ b/src/main/java/me/shedaniel/rei/gui/config/entry/FilteringAddRuleScreen.java @@ -0,0 +1,194 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020 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.gui.config.entry; + +import me.shedaniel.clothconfig2.gui.widget.DynamicElementListWidget; +import me.shedaniel.rei.impl.filtering.FilteringRule; +import me.shedaniel.rei.impl.filtering.rules.ManualFilteringRule; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.LiteralText; +import net.minecraft.text.StringRenderable; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import net.minecraft.util.Identifier; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.function.BiFunction; + +public class FilteringAddRuleScreen extends Screen { + private final FilteringEntry entry; + private RulesList rulesList; + Screen parent; + + public FilteringAddRuleScreen(FilteringEntry entry) { + super(new TranslatableText("config.roughlyenoughitems.filteringRulesScreen.new")); + this.entry = entry; + } + + @Override + protected void init() { + super.init(); + { + Text backText = new LiteralText("↩ ").append(new TranslatableText("gui.back")); + addButton(new ButtonWidget(4, 4, MinecraftClient.getInstance().textRenderer.getWidth(backText) + 10, 20, backText, button -> { + client.openScreen(parent); + this.parent = null; + })); + } + rulesList = addChild(new RulesList(client, width, height, 30, height, BACKGROUND_TEXTURE)); + for (FilteringRule<?> rule : FilteringRule.REGISTRY) { + if (!(rule instanceof ManualFilteringRule)) + rulesList.addItem(new DefaultRuleEntry(parent, entry, rule.createNew(), null)); + } + rulesList.selectItem(rulesList.children().get(0)); + } + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + this.rulesList.render(matrices, mouseX, mouseY, delta); + super.render(matrices, mouseX, mouseY, delta); + this.textRenderer.drawWithShadow(matrices, this.title, this.width / 2.0F - this.textRenderer.getWidth(this.title) / 2.0F, 12.0F, -1); + } + + public static class RulesList extends DynamicElementListWidget<RuleEntry> { + private boolean inFocus; + + public RulesList(MinecraftClient client, int width, int height, int top, int bottom, Identifier backgroundLocation) { + super(client, width, height, top, bottom, backgroundLocation); + } + + @Override + public boolean changeFocus(boolean lookForwards) { + if (!this.inFocus && this.getItemCount() == 0) { + return false; + } else { + this.inFocus = !this.inFocus; + if (this.inFocus && this.getSelectedItem() == null && this.getItemCount() > 0) { + this.moveSelection(1); + } else if (this.inFocus && this.getSelectedItem() != null) { + this.getSelectedItem(); + } + + return this.inFocus; + } + } + + @Override + protected boolean isSelected(int index) { + return Objects.equals(this.getSelectedItem(), this.children().get(index)); + } + + @Override + protected int addItem(RuleEntry item) { + return super.addItem(item); + } + + @Override + public int getItemWidth() { + return width - 40; + } + + @Override + protected int getScrollbarPosition() { + return width - 14; + } + } + + public static abstract class RuleEntry extends DynamicElementListWidget.ElementEntry<RuleEntry> { + private final FilteringRule<?> rule; + + public RuleEntry(FilteringRule<?> rule) { + this.rule = rule; + } + + public FilteringRule<?> getRule() { + return rule; + } + + @Override + public int getItemHeight() { + return 26; + } + + @Override + public boolean changeFocus(boolean lookForwards) { + return false; + } + } + + public static class DefaultRuleEntry extends RuleEntry { + private final ButtonWidget addButton; + private final BiFunction<FilteringEntry, Screen, Screen> screenFunction; + + public DefaultRuleEntry(Screen parent, FilteringEntry entry, FilteringRule<?> rule, BiFunction<FilteringEntry, Screen, Screen> screenFunction) { + super(rule); + this.screenFunction = (screenFunction == null ? rule.createEntryScreen().orElse(null) : screenFunction); + addButton = new ButtonWidget(0, 0, 20, 20, Text.method_30163(" + "), button -> { + entry.edited = true; + MinecraftClient.getInstance().openScreen(this.screenFunction.apply(entry, parent)); + entry.rules.add(0, rule); + }); + addButton.active = this.screenFunction != null; + } + + @Override + public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) { + MinecraftClient client = MinecraftClient.getInstance(); + { + Text title = getRule().getTitle(); + int i = client.textRenderer.getWidth(title); + if (i > entryWidth - 28) { + StringRenderable titleTrimmed = StringRenderable.concat(client.textRenderer.trimToWidth(title, entryWidth - 28 - client.textRenderer.getStringWidth("...")), StringRenderable.plain("...")); + client.textRenderer.drawWithShadow(matrices, titleTrimmed, x + 2, y + 1, 16777215); + } else { + client.textRenderer.drawWithShadow(matrices, title, x + 2, y + 1, 16777215); + } + } + { + Text subtitle = getRule().getSubtitle(); + int i = client.textRenderer.getWidth(subtitle); + if (i > entryWidth - 28) { + StringRenderable subtitleTrimmed = StringRenderable.concat(client.textRenderer.trimToWidth(subtitle, entryWidth - 28 - client.textRenderer.getStringWidth("...")), StringRenderable.plain("...")); + client.textRenderer.drawWithShadow(matrices, subtitleTrimmed, x + 2, y + 12, 8421504); + } else { + client.textRenderer.drawWithShadow(matrices, subtitle, x + 2, y + 12, 8421504); + } + } + addButton.x = x + entryWidth - 25; + addButton.y = y + 1; + addButton.render(matrices, mouseX, mouseY, delta); + } + + @Override + public List<? extends Element> children() { + return Collections.singletonList(addButton); + } + } +} diff --git a/src/main/java/me/shedaniel/rei/gui/config/entry/FilteringEntry.java b/src/main/java/me/shedaniel/rei/gui/config/entry/FilteringEntry.java index 4aecdef6f..1109e6b19 100644 --- a/src/main/java/me/shedaniel/rei/gui/config/entry/FilteringEntry.java +++ b/src/main/java/me/shedaniel/rei/gui/config/entry/FilteringEntry.java @@ -24,8 +24,10 @@ package me.shedaniel.rei.gui.config.entry; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; import me.shedaniel.clothconfig2.api.AbstractConfigListEntry; import me.shedaniel.rei.api.EntryStack; +import me.shedaniel.rei.impl.filtering.FilteringRule; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.Element; import net.minecraft.client.gui.widget.AbstractButtonWidget; @@ -44,22 +46,27 @@ import java.util.function.Consumer; public class FilteringEntry extends AbstractConfigListEntry<List<EntryStack>> { private int width; Consumer<List<EntryStack>> saveConsumer; + Consumer<List<FilteringRule<?>>> rulesSaveConsumer; List<EntryStack> defaultValue; List<EntryStack> configFiltered; + List<FilteringRule<?>> rules; boolean edited = false; - private final FilteringScreen filteringScreen = new FilteringScreen(this); + final FilteringScreen filteringScreen = new FilteringScreen(this); + final FilteringRulesScreen filteringRulesScreen = new FilteringRulesScreen(this); private final AbstractButtonWidget buttonWidget = new ButtonWidget(0, 0, 0, 20, new TranslatableText("config.roughlyenoughitems.filteringScreen"), button -> { - filteringScreen.parent = MinecraftClient.getInstance().currentScreen; - MinecraftClient.getInstance().openScreen(filteringScreen); + filteringRulesScreen.parent = MinecraftClient.getInstance().currentScreen; + MinecraftClient.getInstance().openScreen(filteringRulesScreen); }); private final List<Element> children = ImmutableList.of(buttonWidget); - public FilteringEntry(int width, List<EntryStack> configFiltered, List<EntryStack> defaultValue, Consumer<List<EntryStack>> saveConsumer) { + public FilteringEntry(int width, List<EntryStack> configFiltered, List<FilteringRule<?>> rules, List<EntryStack> defaultValue, Consumer<List<EntryStack>> saveConsumer, Consumer<List<FilteringRule<?>>> rulesSaveConsumer) { super(NarratorManager.EMPTY, false); this.width = width; this.configFiltered = configFiltered; + this.rules = Lists.newArrayList(rules); this.defaultValue = defaultValue; this.saveConsumer = saveConsumer; + this.rulesSaveConsumer = rulesSaveConsumer; } @Override @@ -75,6 +82,7 @@ public class FilteringEntry extends AbstractConfigListEntry<List<EntryStack>> { @Override public void save() { saveConsumer.accept(getValue()); + rulesSaveConsumer.accept(rules); this.edited = false; } diff --git a/src/main/java/me/shedaniel/rei/gui/config/entry/FilteringRuleOptionsScreen.java b/src/main/java/me/shedaniel/rei/gui/config/entry/FilteringRuleOptionsScreen.java new file mode 100644 index 000000000..21b0e0440 --- /dev/null +++ b/src/main/java/me/shedaniel/rei/gui/config/entry/FilteringRuleOptionsScreen.java @@ -0,0 +1,239 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020 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.gui.config.entry; + +import me.shedaniel.clothconfig2.gui.widget.DynamicElementListWidget; +import me.shedaniel.rei.impl.filtering.FilteringRule; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.TextFieldWidget; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.StringRenderable; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import net.minecraft.util.Identifier; + +import java.util.Collections; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; + +public abstract class FilteringRuleOptionsScreen<T extends FilteringRule<?>> extends Screen { + private final FilteringEntry entry; + private RulesList rulesList; + Screen parent; + public T rule; + + public FilteringRuleOptionsScreen(FilteringEntry entry, T rule, Screen screen) { + super(new TranslatableText("config.roughlyenoughitems.filteringRulesScreen")); + this.entry = entry; + this.rule = rule; + this.parent = screen; + } + + @Override + protected void init() { + super.init(); + if (rulesList != null) save(); + { + Text doneText = new TranslatableText("gui.done"); + int width = MinecraftClient.getInstance().textRenderer.getWidth(doneText); + addButton(new ButtonWidget(this.width - 4 - width - 10, 4, width + 10, 20, doneText, button -> { + save(); + client.openScreen(parent); + })); + } + rulesList = addChild(new RulesList(client, width, height, 30, height, BACKGROUND_TEXTURE)); + addEntries(ruleEntry -> rulesList.addItem(ruleEntry)); + } + + public abstract void addEntries(Consumer<RuleEntry> entryConsumer); + + public abstract void save(); + + public void addText(Consumer<RuleEntry> entryConsumer, StringRenderable text) { + for (StringRenderable s : textRenderer.wrapStringToWidthAsList(text, width - 80)) { + entryConsumer.accept(new TextRuleEntry(rule, s)); + } + } + + public void addEmpty(Consumer<RuleEntry> entryConsumer, int height) { + entryConsumer.accept(new EmptyRuleEntry(rule, height)); + } + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + this.rulesList.render(matrices, mouseX, mouseY, delta); + super.render(matrices, mouseX, mouseY, delta); + this.textRenderer.drawWithShadow(matrices, this.title, this.width / 2.0F - this.textRenderer.getWidth(this.title) / 2.0F, 12.0F, -1); + } + + public static class RulesList extends DynamicElementListWidget<RuleEntry> { + public RulesList(MinecraftClient client, int width, int height, int top, int bottom, Identifier backgroundLocation) { + super(client, width, height, top, bottom, backgroundLocation); + } + + @Override + protected int addItem(RuleEntry item) { + return super.addItem(item); + } + + @Override + public int getItemWidth() { + return width - 40; + } + + @Override + protected int getScrollbarPosition() { + return width - 14; + } + } + + public static abstract class RuleEntry extends DynamicElementListWidget.ElementEntry<RuleEntry> { + private final FilteringRule<?> rule; + + public RuleEntry(FilteringRule<?> rule) { + this.rule = rule; + } + + public FilteringRule<?> getRule() { + return rule; + } + } + + public static class TextRuleEntry extends RuleEntry { + private final StringRenderable text; + + public TextRuleEntry(FilteringRule<?> rule, StringRenderable text) { + super(rule); + this.text = text; + } + + @Override + public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) { + MinecraftClient.getInstance().textRenderer.drawWithShadow(matrices, text, x + 5, y, -1); + } + + @Override + public int getItemHeight() { + return 12; + } + + @Override + public List<? extends Element> children() { + return Collections.emptyList(); + } + } + + public static class EmptyRuleEntry extends RuleEntry { + private final int height; + + public EmptyRuleEntry(FilteringRule<?> rule, int height) { + super(rule); + this.height = height; + } + + @Override + public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) { + } + + @Override + public int getItemHeight() { + return height; + } + + @Override + public List<? extends Element> children() { + return Collections.emptyList(); + } + } + + public static class TextFieldRuleEntry extends RuleEntry { + private final TextFieldWidget widget; + + public TextFieldRuleEntry(int width, FilteringRule<?> rule, Consumer<TextFieldWidget> widgetConsumer) { + super(rule); + this.widget = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, 0, 0, width, 18, Text.method_30163("")); + widgetConsumer.accept(widget); + } + + @Override + public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) { + widget.x = x + 2; + widget.y = y + 2; + widget.render(matrices, mouseX, mouseY, delta); + } + + @Override + public int getItemHeight() { + return 20; + } + + public TextFieldWidget getWidget() { + return widget; + } + + @Override + public List<? extends Element> children() { + return Collections.singletonList(widget); + } + } + + public static class BooleanRuleEntry extends RuleEntry { + private boolean b; + private final ButtonWidget widget; + + public BooleanRuleEntry(int width, boolean b, FilteringRule<?> rule, Function<Boolean, Text> textFunction) { + super(rule); + this.b = b; + this.widget = new ButtonWidget(0, 0, 100, 20, textFunction.apply(b), button -> { + this.b = !this.b; + button.setMessage(textFunction.apply(this.b)); + }); + } + + public boolean getBoolean() { + return b; + } + + @Override + public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) { + widget.x = x + 2; + widget.y = y; + widget.render(matrices, mouseX, mouseY, delta); + } + + @Override + public int getItemHeight() { + return 20; + } + + @Override + public List<? extends Element> children() { + return Collections.singletonList(widget); + } + } +} diff --git a/src/main/java/me/shedaniel/rei/gui/config/entry/FilteringRulesScreen.java b/src/main/java/me/shedaniel/rei/gui/config/entry/FilteringRulesScreen.java new file mode 100644 index 000000000..8e5a3adae --- /dev/null +++ b/src/main/java/me/shedaniel/rei/gui/config/entry/FilteringRulesScreen.java @@ -0,0 +1,246 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020 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.gui.config.entry; + +import me.shedaniel.clothconfig2.gui.widget.DynamicElementListWidget; +import me.shedaniel.rei.impl.filtering.FilteringRule; +import me.shedaniel.rei.impl.filtering.rules.ManualFilteringRule; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.sound.PositionedSoundInstance; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.sound.SoundEvents; +import net.minecraft.text.LiteralText; +import net.minecraft.text.StringRenderable; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import net.minecraft.util.Identifier; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.function.BiFunction; + +import static me.shedaniel.rei.gui.RecipeViewingScreen.CHEST_GUI_TEXTURE; + +public class FilteringRulesScreen extends Screen { + private final FilteringEntry entry; + private RulesList rulesList; + Screen parent; + + public FilteringRulesScreen(FilteringEntry entry) { + super(new TranslatableText("config.roughlyenoughitems.filteringRulesScreen")); + this.entry = entry; + } + + @Override + protected void init() { + super.init(); + { + Text backText = new LiteralText("↩ ").append(new TranslatableText("gui.back")); + addButton(new ButtonWidget(4, 4, MinecraftClient.getInstance().textRenderer.getWidth(backText) + 10, 20, backText, button -> { + client.openScreen(parent); + this.parent = null; + })); + } + { + Text addText = new LiteralText(" + "); + addButton(new ButtonWidget(width - 4 - 20, 4, 20, 20, addText, button -> { + FilteringAddRuleScreen screen = new FilteringAddRuleScreen(entry); + screen.parent = this; + client.openScreen(screen); + })); + } + rulesList = addChild(new RulesList(client, width, height, 30, height, BACKGROUND_TEXTURE)); + for (int i = entry.rules.size() - 1; i >= 0; i--) { + FilteringRule<?> rule = entry.rules.get(i); + if (rule instanceof ManualFilteringRule) + rulesList.addItem(new DefaultRuleEntry(rule, entry, (entry, screen) -> { + entry.filteringScreen.parent = screen; + return entry.filteringScreen; + })); + else rulesList.addItem(new DefaultRuleEntry(rule, entry, null)); + } + rulesList.selectItem(rulesList.children().get(0)); + } + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + this.rulesList.render(matrices, mouseX, mouseY, delta); + super.render(matrices, mouseX, mouseY, delta); + this.textRenderer.drawWithShadow(matrices, this.title, this.width / 2.0F - this.textRenderer.getWidth(this.title) / 2.0F, 12.0F, -1); + } + + public static class RulesList extends DynamicElementListWidget<RuleEntry> { + private boolean inFocus; + + public RulesList(MinecraftClient client, int width, int height, int top, int bottom, Identifier backgroundLocation) { + super(client, width, height, top, bottom, backgroundLocation); + } + + @Override + public boolean changeFocus(boolean lookForwards) { + if (!this.inFocus && this.getItemCount() == 0) { + return false; + } else { + this.inFocus = !this.inFocus; + if (t |
