diff options
| author | shedaniel <daniel@shedaniel.me> | 2022-11-05 01:15:41 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2023-05-29 21:19:00 +0800 |
| commit | 8626c1a09f939913cb397520cf2c69c281cabe20 (patch) | |
| tree | 97997c9c0102348b9cb9cfc6ed2302518b161a64 /runtime/src/main/java | |
| parent | bca8c6dfa773a549e8e110f88dff37689baebf30 (diff) | |
| download | RoughlyEnoughItems-8626c1a09f939913cb397520cf2c69c281cabe20.tar.gz RoughlyEnoughItems-8626c1a09f939913cb397520cf2c69c281cabe20.tar.bz2 RoughlyEnoughItems-8626c1a09f939913cb397520cf2c69c281cabe20.zip | |
Fix #1187
Diffstat (limited to 'runtime/src/main/java')
7 files changed, 527 insertions, 14 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java index 41db7c7ed..8858445c7 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java @@ -59,6 +59,7 @@ import me.shedaniel.rei.api.client.gui.config.DisplayScreenType; import me.shedaniel.rei.api.client.gui.config.SyntaxHighlightingMode; import me.shedaniel.rei.api.client.overlay.ScreenOverlay; import me.shedaniel.rei.api.client.registry.entry.EntryRegistry; +import me.shedaniel.rei.api.common.category.CategoryIdentifier; import me.shedaniel.rei.api.common.entry.EntryStack; import me.shedaniel.rei.api.common.util.CollectionUtils; import me.shedaniel.rei.api.common.util.ImmutableTextComponent; @@ -72,6 +73,7 @@ import me.shedaniel.rei.impl.common.InternalLogger; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.ChatFormatting; +import net.minecraft.ResourceLocationException; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.events.GuiEventListener; @@ -132,6 +134,18 @@ public class ConfigManagerImpl implements ConfigManager { Collections.singletonList(new FilteringEntry(220, value, ((ConfigObjectImpl.Advanced.Filtering) config).filteringRules, defaultValue, saveConsumer, list -> ((ConfigObjectImpl.Advanced.Filtering) config).filteringRules = Lists.newArrayList(list))); } , (field) -> field.getType() == List.class, ConfigObjectImpl.UseFilteringScreen.class); + guiRegistry.registerAnnotationProvider((i13n, field, config, defaults, guiProvider) -> { + Map<CategoryIdentifier<?>, Boolean> value = Utils.<Map<CategoryIdentifier<?>, Boolean>>getUnsafely(field, config, new HashMap<>()); + Map<CategoryIdentifier<?>, Boolean> defaultValue = Utils.getUnsafely(field, defaults); + Consumer<Map<CategoryIdentifier<?>, Boolean>> saveConsumer = (newValue) -> { + setUnsafely(field, config, newValue); + }; + return REIRuntime.getInstance().getPreviousContainerScreen() == null || Minecraft.getInstance().getConnection() == null || Minecraft.getInstance().getConnection().getRecipeManager() == null ? + Collections.singletonList(new NoFilteringCategoriesEntry(new TranslatableComponent(i13n), value, defaultValue, saveConsumer)) + : + Collections.singletonList(new FilteringCategoriesEntry(new TranslatableComponent(i13n), value, defaultValue, saveConsumer)); + } + , (field) -> field.getType() == Map.class, ConfigObjectImpl.UseFilteringCategoriesScreen.class); InternalLogger.getInstance().info("Config loaded"); saveConfig(); } @@ -279,6 +293,18 @@ public class ConfigManagerImpl implements ConfigManager { } }); + // CategoryIdentifier + builder.registerSerializer(CategoryIdentifier.class, (value, marshaller) -> { + return marshaller.serialize(value.toString()); + }); + builder.registerDeserializer(String.class, CategoryIdentifier.class, (value, marshaller) -> { + try { + return CategoryIdentifier.of(value); + } catch (ResourceLocationException e) { + throw new DeserializationException(e); + } + }); + return builder.build(); } @@ -372,12 +398,12 @@ public class ConfigManagerImpl implements ConfigManager { if (Minecraft.getInstance().getConnection() != null && Minecraft.getInstance().getConnection().getRecipeManager() != null) { TextListEntry feedbackEntry = ConfigEntryBuilder.create().startTextDescription( new TranslatableComponent("text.rei.feedback", new TranslatableComponent("text.rei.feedback.link") - .withStyle(style -> style - .withColor(TextColor.fromRgb(0xff1fc3ff)) - .withUnderlined(true) - .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://forms.gle/5tdnK5WN1wng78pV8")) + .withStyle(style -> style + .withColor(TextColor.fromRgb(0xff1fc3ff)) + .withUnderlined(true) + .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://forms.gle/5tdnK5WN1wng78pV8")) .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ImmutableTextComponent("https://forms.gle/5tdnK5WN1wng78pV8"))) - )) + )) .withStyle(ChatFormatting.GRAY) ).build(); builder.getOrCreateCategory(new TranslatableComponent("config.roughlyenoughitems.advanced")).getEntries().add(0, feedbackEntry); @@ -396,18 +422,18 @@ public class ConfigManagerImpl implements ConfigManager { TextListEntry supportText = ConfigEntryBuilder.create().startTextDescription( new TranslatableComponent("text.rei.support.me.desc", new TranslatableComponent("text.rei.support.me.patreon") - .withStyle(style -> style - .withColor(TextColor.fromRgb(0xff1fc3ff)) - .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://patreon.com/shedaniel")) + .withStyle(style -> style + .withColor(TextColor.fromRgb(0xff1fc3ff)) + .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://patreon.com/shedaniel")) .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ImmutableTextComponent("https://patreon.com/shedaniel"))) - ), + ), new TranslatableComponent("text.rei.support.me.bisect") - .withStyle(style -> style - .withColor(TextColor.fromRgb(0xff1fc3ff)) - .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://www.bisecthosting.com/shedaniel")) + .withStyle(style -> style + .withColor(TextColor.fromRgb(0xff1fc3ff)) + .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://www.bisecthosting.com/shedaniel")) .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ImmutableTextComponent("https://www.bisecthosting.com/shedaniel"))) - ) - ) + ) + ) .withStyle(ChatFormatting.GRAY) ).build(); supportText.setScreen((AbstractConfigScreen) screen); 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 b92f89b4a..746e11b54 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java @@ -39,6 +39,7 @@ import me.shedaniel.rei.api.client.gui.config.*; import me.shedaniel.rei.api.common.entry.EntryStack; import me.shedaniel.rei.api.common.util.CollectionUtils; import me.shedaniel.rei.impl.client.entry.filtering.FilteringRule; +import me.shedaniel.rei.api.common.category.CategoryIdentifier; import me.shedaniel.rei.impl.client.gui.widget.favorites.FavoritesEntriesManager; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -56,7 +57,9 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; @ApiStatus.Internal @Config(name = "roughlyenoughitems/config") @@ -413,6 +416,12 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { return advanced.filtering.filteringRules; } + @ApiStatus.Experimental + @Override + public Map<CategoryIdentifier<?>, Boolean> getFilteringQuickCraftCategories() { + return advanced.filtering.filteringQuickCraftCategories; + } + @Override @ApiStatus.Experimental public boolean shouldAsyncSearch() { @@ -548,6 +557,10 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD}) + @interface UseFilteringCategoriesScreen {} + + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.FIELD}) @interface UsePercentage { double min(); @@ -708,6 +721,7 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { @UseFilteringScreen private List<EntryStackProvider<?>> filteredStacks = new ArrayList<>(); public boolean shouldFilterDisplays = true; @ConfigEntry.Gui.Excluded public List<FilteringRule<?>> filteringRules = new ArrayList<>(); + @UseFilteringCategoriesScreen public Map<CategoryIdentifier<?>, Boolean> filteringQuickCraftCategories = new HashMap<>(); } } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringCategoriesEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringCategoriesEntry.java new file mode 100644 index 000000000..5e1f41a32 --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringCategoriesEntry.java @@ -0,0 +1,113 @@ +/* + * 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.config.entries; + +import com.google.common.collect.ImmutableList; +import com.mojang.blaze3d.platform.Window; +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.clothconfig2.api.AbstractConfigListEntry; +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.narration.NarratableEntry; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TranslatableComponent; +import org.jetbrains.annotations.ApiStatus; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Consumer; + +@ApiStatus.Internal +public class FilteringCategoriesEntry extends AbstractConfigListEntry<Map<CategoryIdentifier<?>, Boolean>> { + private Consumer<Map<CategoryIdentifier<?>, Boolean>> saveConsumer; + private Map<CategoryIdentifier<?>, Boolean> defaultValue; + private Map<CategoryIdentifier<?>, Boolean> configFiltered; + final FilteringCategoriesScreen filteringScreen = new FilteringCategoriesScreen(this); + boolean edited = false; + private final AbstractWidget buttonWidget = new Button(0, 0, 150, 20, new TranslatableComponent("config.roughlyenoughitems.filtering.excludedQuickCraftCategories.configure"), button -> { + filteringScreen.parent = Minecraft.getInstance().screen; + Minecraft.getInstance().setScreen(filteringScreen); + }); + private final List<AbstractWidget> children = ImmutableList.of(buttonWidget); + + public FilteringCategoriesEntry(Component fieldName, Map<CategoryIdentifier<?>, Boolean> configFiltered, Map<CategoryIdentifier<?>, Boolean> defaultValue, Consumer<Map<CategoryIdentifier<?>, Boolean>> saveConsumer) { + super(fieldName, false); + this.configFiltered = configFiltered; + this.defaultValue = defaultValue; + this.saveConsumer = saveConsumer; + } + + @Override + public Map<CategoryIdentifier<?>, Boolean> getValue() { + return configFiltered; + } + + @Override + public Optional<Map<CategoryIdentifier<?>, Boolean>> getDefaultValue() { + return Optional.ofNullable(defaultValue); + } + + @Override + public void save() { + saveConsumer.accept(getValue()); + this.edited = false; + } + + @Override + public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) { + super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta); + Window window = Minecraft.getInstance().getWindow(); + this.buttonWidget.y = y; + + Component displayedFieldName = this.getDisplayedFieldName(); + if (Minecraft.getInstance().font.isBidirectional()) { + Minecraft.getInstance().font.drawShadow(matrices, displayedFieldName.getVisualOrderText(), (float) (window.getGuiScaledWidth() - x - Minecraft.getInstance().font.width(displayedFieldName)), (float) (y + 6), 16777215); + this.buttonWidget.x = x + 2; + } else { + Minecraft.getInstance().font.drawShadow(matrices, displayedFieldName.getVisualOrderText(), (float) x, (float) (y + 6), this.getPreferredTextColor()); + this.buttonWidget.x = x + entryWidth - 150; + } + + this.buttonWidget.render(matrices, mouseX, mouseY, delta); + } + + @Override + public List<? extends GuiEventListener> children() { + return children; + } + + @Override + public List<? extends NarratableEntry> narratables() { + return children; + } + + @Override + public boolean isEdited() { + return super.isEdited() || edited; + } +} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringCategoriesScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringCategoriesScreen.java new file mode 100644 index 000000000..e5e9324ad --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringCategoriesScreen.java @@ -0,0 +1,244 @@ +/* + * 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.config.entries; + +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.clothconfig2.gui.widget.DynamicElementListWidget; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.registry.category.CategoryRegistry; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.Button; +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.locale.Language; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.FormattedText; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundEvents; + +import java.util.Collections; +import java.util.List; + +public class FilteringCategoriesScreen extends Screen { + private final FilteringCategoriesEntry entry; + private ListWidget listWidget; + Screen parent; + + public FilteringCategoriesScreen(FilteringCategoriesEntry entry) { + super(new TranslatableComponent("config.roughlyenoughitems.filtering.excludedQuickCraftCategories.configure.title")); + this.entry = entry; + } + + @Override + public void init() { + super.init(); + { + Component backText = new TextComponent("↩ ").append(new TranslatableComponent("gui.back")); + addRenderableWidget(new Button(4, 4, Minecraft.getInstance().font.width(backText) + 10, 20, backText, button -> { + minecraft.setScreen(parent); + this.parent = null; + })); + } + listWidget = addWidget(new ListWidget(minecraft, width, height, 30, height, BACKGROUND_LOCATION)); + for (CategoryRegistry.CategoryConfiguration<?> configuration : CategoryRegistry.getInstance()) { + listWidget.addItem(new DefaultListEntry(configuration)); + } + } + + @Override + public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { + this.listWidget.render(matrices, mouseX, mouseY, delta); + super.render(matrices, mouseX, mouseY, delta); + this.font.drawShadow(matrices, this.title.getVisualOrderText(), this.width / 2.0F - this.font.width(this.title) / 2.0F, 12.0F, -1); + } + + private static class ListWidget extends DynamicElementListWidget<ListEntry> { + private boolean inFocus; + + public ListWidget(Minecraft client, int width, int height, int top, int bottom, ResourceLocation 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 false; + } + + @Override + public ListEntry getSelectedItem() { + return null; + } + + @Override + protected int addItem(ListEntry item) { + return super.addItem(item); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (super.mouseClicked(mouseX, mouseY, button)) + return true; + ListEntry item = getItemAtPosition(mouseX, mouseY); + if (item != null) { + client.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F)); + selectItem(item); + this.setFocused(item); + this.setDragging(true); + return true; + } + return false; + } + + @Override + public int getItemWidth() { + return width - 40; + } + + @Override + protected int getScrollbarPosition() { + return width - 14; + } + } + + private static abstract class ListEntry extends DynamicElementListWidget.ElementEntry<ListEntry> { + @Override + public int getItemHeight() { + return 35; + } + + @Override + public boolean changeFocus(boolean lookForwards) { + return false; + } + } + + private class DefaultListEntry extends ListEntry { + private final Button toggleButton; + private final CategoryRegistry.CategoryConfiguration<?> configuration; + + public DefaultListEntry(CategoryRegistry.CategoryConfiguration<?> configuration) { + this.configuration = configuration; + { + Component toggleText = new TranslatableComponent("config.roughlyenoughitems.filtering.excludedQuickCraftCategories.configure.toggle"); + toggleButton = new Button(0, 0, Minecraft.getInstance().font.width(toggleText) + 10, 20, toggleText, button -> { + boolean quickCraftingEnabledByDefault = configuration.isQuickCraftingEnabledByDefault(); + boolean enabled = entry.getValue().getOrDefault(configuration.getCategoryIdentifier(), quickCraftingEnabledByDefault); + if (enabled) { + // set to false + if (!quickCraftingEnabledByDefault) { + entry.getValue().remove(configuration.getCategoryIdentifier()); + } else { + entry.getValue().put(configuration.getCategoryIdentifier(), false); + } + } else { + // set to true + if (quickCraftingEnabledByDefault) { + entry.getValue().remove(configuration.getCategoryIdentifier()); + } else { + entry.getValue().put(configuration.getCategoryIdentifier(), true); + } + } + + entry.edited = true; + }); + } + } + + @Override + public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) { + Minecraft client = Minecraft.getInstance(); + matrices.pushPose(); + matrices.translate(0, 0, 100); + configuration.getCategory().getIcon().render(matrices, new Rectangle(x + 2, y + 5, 16, 16), mouseY, mouseY, delta); + matrices.popPose(); + int xPos = x + 22; + { + Component title = configuration.getCategory().getTitle(); + int i = client.font.width(title); + if (i > entryWidth - 28) { + FormattedText titleTrimmed = FormattedText.composite(client.font.substrByWidth(title, entryWidth - 28 - client.font.width("...")), FormattedText.of("...")); + client.font.drawShadow(matrices, Language.getInstance().getVisualOrder(titleTrimmed), x + 2, y + 1, 16777215); + } else { + client.font.drawShadow(matrices, title.getVisualOrderText(), xPos, y + 1, 16777215); + } + } + { + Component subtitle = new TranslatableComponent("config.roughlyenoughitems.filtering.excludedQuickCraftCategories.configure." + entry.getValue().getOrDefault(configuration.getCategoryIdentifier(), configuration.isQuickCraftingEnabledByDefault())) + .withStyle(ChatFormatting.GRAY); + int i = client.font.width(subtitle); + if (i > entryWidth - 28) { + FormattedText subtitleTrimmed = FormattedText.composite(client.font.substrByWidth(subtitle, entryWidth - 28 - client.font.width("...")), FormattedText.of("...")); + client.font.drawShadow(matrices, Language.getInstance().getVisualOrder(subtitleTrimmed), x + 2, y + 12, 8421504); + } else { + client.font.drawShadow(matrices, subtitle.getVisualOrderText(), xPos, y + 12, 8421504); + } + } + { + Component id = new TextComponent(configuration.getCategoryIdentifier().toString()) + .withStyle(ChatFormatting.DARK_GRAY); + int i = client.font.width(id); + if (i > entryWidth - 28) { + FormattedText idTrimmed = FormattedText.composite(client.font.substrByWidth(id, entryWidth - 28 - client.font.width("...")), FormattedText.of("...")); + client.font.drawShadow(matrices, Language.getInstance().getVisualOrder(idTrimmed), x + 2, y + 22, 8421504); + } else { + client.font.drawShadow(matrices, id.getVisualOrderText(), xPos, y + 22, 8421504); + } + } + toggleButton.x = x + entryWidth - 6 - toggleButton.getWidth(); + toggleButton.y = y + 5; + toggleButton.render(matrices, mouseX, mouseY, delta); + } + + @Override + public List<? extends GuiEventListener> children() { + return Collections.singletonList(toggleButton); + } + + @Override + public List<? extends NarratableEntry> narratables() { + return Collections.singletonList(toggleButton); + } + } +} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/NoFilteringCategoriesEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/NoFilteringCategoriesEntry.java new file mode 100644 index 000000000..60ce79802 --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/NoFilteringCategoriesEntry.java @@ -0,0 +1,103 @@ +/* + * 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.config.entries; + +import com.google.common.collect.ImmutableList; +import com.mojang.blaze3d.platform.Window; +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.clothconfig2.api.AbstractConfigListEntry; +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.narration.NarratableEntry; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TranslatableComponent; +import org.jetbrains.annotations.ApiStatus; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Consumer; + +@ApiStatus.Internal +public class NoFilteringCategoriesEntry extends AbstractConfigListEntry<Map<CategoryIdentifier<?>, Boolean>> { + private Consumer<Map<CategoryIdentifier<?>, Boolean>> saveConsumer; + private Map<CategoryIdentifier<?>, Boolean> defaultValue; + private Map<CategoryIdentifier<?>, Boolean> configFiltered; + private final AbstractWidget buttonWidget = new Button(0, 0, 150, 20, new TranslatableComponent("config.roughlyenoughitems.filteredEntries.loadWorldFirst"), button -> {}); + private final List<AbstractWidget> children = ImmutableList.of(buttonWidget); + + public NoFilteringCategoriesEntry(Component fieldName, Map<CategoryIdentifier<?>, Boolean> configFiltered, Map<CategoryIdentifier<?>, Boolean> defaultValue, Consumer<Map<CategoryIdentifier<?>, Boolean>> saveConsumer) { + super(fieldName, false); + this.configFiltered = configFiltered; + this.defaultValue = defaultValue; + this.saveConsumer = saveConsumer; + } + + @Override + public Map<CategoryIdentifier<?>, Boolean> getValue() { + return configFiltered; + } + + @Override + public Optional<Map<CategoryIdentifier<?>, Boolean>> getDefaultValue() { + return Optional.ofNullable(defaultValue); + } + + @Override + public void save() { + saveConsumer.accept(getValue()); + } + + @Override + public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) { + super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta); + Window window = Minecraft.getInstance().getWindow(); + this.buttonWidget.active = false; + this.buttonWidget.y = y; + + Component displayedFieldName = this.getDisplayedFieldName(); + if (Minecraft.getInstance().font.isBidirectional()) { + Minecraft.getInstance().font.drawShadow(matrices, displayedFieldName.getVisualOrderText(), (float) (window.getGuiScaledWidth() - x - Minecraft.getInstance().font.width(displayedFieldName)), (float) (y + 6), 16777215); + this.buttonWidget.x = x + 2; + } else { + Minecraft.getInstance().font.drawShadow(matrices, displayedFieldName.getVisualOrderText(), (float) x, (float) (y + 6), this.getPreferredTextColor()); + this.buttonWidget.x = x + entryWidth - 150; + } + + this.buttonWidget.render(matrices, mouseX, mouseY, delta); + } + + @Override + public List<? extends GuiEventListener> children() { + return children; + } + + @Override + public List<? extends NarratableEntry> narratables() { + return children; + } +} 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 ce27e5c85..f73e158fa 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 @@ -319,10 +319,12 @@ public class EntryWidget extends Slot implements DraggableStackProviderWidget { try { DisplayRegistry displayRegistry = DisplayRegistry.getInstance(); CategoryRegistry categoryRegistry = CategoryRegistry.getInstance(); + Map<CategoryIdentifier<?>, Boolean> filteringQuickCraftCategories = ConfigObject.getInstance().getFilteringQuickCraftCategories(); for (Map.Entry<CategoryIdentifier<?>, List<Display>> entry : displayRegistry.getAll().entrySet()) { Optional<? extends CategoryRegistry.CategoryConfiguration<?>> configuration; if ((configuration = categoryRegistry.tryGet(entry.getKey())).isEmpty() || categoryRegistry.isCategoryInvisible(configuration.get().getCategory())) continue; + if (!filteringQuickCraftCategories.getOrDefault(entry.getKey(), configuration.get().isQuickCraftingEnabledByDefault())) continue; for (Display display : entry.getValue()) { if ((!ConfigObject.getInstance().shouldFilterDisplays() || displayRegistry.isDisplayVisible(display)) && ViewsImpl.isRecipesFor(getEntries(), display)) { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/category/CategoryRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/category/CategoryRegistryImpl.java index ca5206299..21cc60e81 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/category/CategoryRegistryImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/category/CategoryRegistryImp |
