From 4755b58cc468d8711f21c42fb2f51357da5ca851 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Thu, 11 Jun 2020 19:15:16 +0800 Subject: Rewritten Config Screen Signed-off-by: shedaniel --- .../me/shedaniel/rei/RoughlyEnoughItemsCore.java | 8 +- .../java/me/shedaniel/rei/api/ConfigObject.java | 8 +- .../shedaniel/rei/gui/PreRecipeViewingScreen.java | 5 +- .../shedaniel/rei/gui/RecipeDisplayExporter.java | 5 +- .../shedaniel/rei/gui/WarningAndErrorScreen.java | 20 +- .../shedaniel/rei/gui/config/AppearanceTheme.java | 40 ++ .../rei/gui/config/ConfigButtonPosition.java | 40 ++ .../rei/gui/config/DisplayPanelLocation.java | 40 ++ .../rei/gui/config/EntryPanelOrdering.java | 45 ++ .../rei/gui/config/EntryPanelOrderingConfig.java | 63 +++ .../shedaniel/rei/gui/config/ItemListOrdering.java | 45 -- .../rei/gui/config/ItemListOrderingConfig.java | 63 --- .../rei/gui/config/SearchFieldLocation.java | 2 +- .../rei/gui/config/entry/FilteringEntry.java | 420 ++--------------- .../rei/gui/config/entry/FilteringScreen.java | 510 +++++++++++++++++++++ .../rei/gui/config/entry/NoFilteringEntry.java | 29 +- .../gui/config/entry/RecipeScreenTypeEntry.java | 8 +- .../rei/gui/config/entry/ReloadPluginsEntry.java | 94 ++++ .../rei/gui/credits/CreditsEntryListWidget.java | 6 +- .../shedaniel/rei/gui/widget/EntryListWidget.java | 9 +- .../rei/gui/widget/FavoritesListWidget.java | 14 +- .../me/shedaniel/rei/impl/ConfigManagerImpl.java | 29 +- .../me/shedaniel/rei/impl/ConfigObjectImpl.java | 271 ++++++----- .../java/me/shedaniel/rei/impl/ScreenHelper.java | 2 +- .../information/DefaultInformationCategory.java | 10 +- 25 files changed, 1078 insertions(+), 708 deletions(-) create mode 100644 src/main/java/me/shedaniel/rei/gui/config/AppearanceTheme.java create mode 100644 src/main/java/me/shedaniel/rei/gui/config/ConfigButtonPosition.java create mode 100644 src/main/java/me/shedaniel/rei/gui/config/DisplayPanelLocation.java create mode 100644 src/main/java/me/shedaniel/rei/gui/config/EntryPanelOrdering.java create mode 100644 src/main/java/me/shedaniel/rei/gui/config/EntryPanelOrderingConfig.java delete mode 100644 src/main/java/me/shedaniel/rei/gui/config/ItemListOrdering.java delete mode 100644 src/main/java/me/shedaniel/rei/gui/config/ItemListOrderingConfig.java create mode 100644 src/main/java/me/shedaniel/rei/gui/config/entry/FilteringScreen.java create mode 100644 src/main/java/me/shedaniel/rei/gui/config/entry/ReloadPluginsEntry.java (limited to 'src/main/java') diff --git a/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java b/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java index c9a5a45ba..85e8bd694 100644 --- a/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java +++ b/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java @@ -25,7 +25,7 @@ package me.shedaniel.rei; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import me.shedaniel.cloth.hooks.ClothClientHooks; +import me.shedaniel.cloth.api.client.events.v0.ClothClientHooks; import me.shedaniel.math.api.Executor; import me.shedaniel.rei.api.*; import me.shedaniel.rei.api.plugins.REIPluginV0; @@ -321,14 +321,14 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer { if (screen instanceof ContainerScreen) ScreenHelper.setPreviousContainerScreen((ContainerScreen) screen); boolean alreadyAdded = false; - for (Element element : Lists.newArrayList(screenHooks.cloth_getChildren())) + for (Element element : Lists.newArrayList(screenHooks.cloth$getChildren())) if (ContainerScreenOverlay.class.isAssignableFrom(element.getClass())) if (alreadyAdded) - screenHooks.cloth_getChildren().remove(element); + screenHooks.cloth$getChildren().remove(element); else alreadyAdded = true; if (!alreadyAdded) - screenHooks.cloth_getChildren().add(ScreenHelper.getLastOverlay(true, false)); + screenHooks.cloth$getChildren().add(ScreenHelper.getLastOverlay(true, false)); }); ClothClientHooks.SCREEN_RENDER_POST.register((matrices, minecraftClient, screen, i, i1, v) -> { if (shouldReturn(screen)) diff --git a/src/main/java/me/shedaniel/rei/api/ConfigObject.java b/src/main/java/me/shedaniel/rei/api/ConfigObject.java index 52b7fe664..448c3ccb8 100644 --- a/src/main/java/me/shedaniel/rei/api/ConfigObject.java +++ b/src/main/java/me/shedaniel/rei/api/ConfigObject.java @@ -24,12 +24,11 @@ package me.shedaniel.rei.api; import me.shedaniel.clothconfig2.api.ModifierKeyCode; -import me.shedaniel.rei.gui.config.ItemListOrdering; +import me.shedaniel.rei.gui.config.EntryPanelOrdering; import me.shedaniel.rei.gui.config.RecipeBorderType; import me.shedaniel.rei.gui.config.RecipeScreenType; import me.shedaniel.rei.gui.config.SearchFieldLocation; import me.shedaniel.rei.impl.ConfigManagerImpl; -import me.shedaniel.rei.impl.ConfigObjectImpl; import org.jetbrains.annotations.ApiStatus; import java.util.List; @@ -51,7 +50,7 @@ public interface ConfigObject { void setCheating(boolean cheating); - ItemListOrdering getItemListOrdering(); + EntryPanelOrdering getItemListOrdering(); boolean isItemListAscending(); @@ -137,9 +136,6 @@ public interface ConfigObject { double getEntrySize(); - @ApiStatus.Internal - ConfigObjectImpl.General getGeneral(); - boolean isUsingCompactTabs(); boolean isLowerConfigButton(); diff --git a/src/main/java/me/shedaniel/rei/gui/PreRecipeViewingScreen.java b/src/main/java/me/shedaniel/rei/gui/PreRecipeViewingScreen.java index d57a9bbfd..28faa8b37 100644 --- a/src/main/java/me/shedaniel/rei/gui/PreRecipeViewingScreen.java +++ b/src/main/java/me/shedaniel/rei/gui/PreRecipeViewingScreen.java @@ -34,14 +34,13 @@ import me.shedaniel.rei.gui.config.RecipeScreenType; import me.shedaniel.rei.gui.widget.Widget; import me.shedaniel.rei.gui.widget.WidgetWithBounds; import me.shedaniel.rei.impl.ScreenHelper; -import net.minecraft.class_5348; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.Element; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.ContainerScreen; import net.minecraft.client.util.NarratorManager; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.Text; +import net.minecraft.text.StringRenderable; import net.minecraft.text.TranslatableText; import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; @@ -128,7 +127,7 @@ public class PreRecipeViewingScreen extends Screen { this.drawCenteredText(matrices, this.textRenderer, this.title, this.width / 2, 20, 16777215); if (showTips) { int i = 30; - for (class_5348 s : this.textRenderer.wrapStringToWidthAsList(new TranslatableText("text.rei.recipe_screen_type.selection.sub").formatted(Formatting.GRAY), width - 30)) { + for (StringRenderable s : this.textRenderer.wrapStringToWidthAsList(new TranslatableText("text.rei.recipe_screen_type.selection.sub").formatted(Formatting.GRAY), width - 30)) { this.drawCenteredText(matrices, this.textRenderer, s, width / 2, i, -1); i += 10; } diff --git a/src/main/java/me/shedaniel/rei/gui/RecipeDisplayExporter.java b/src/main/java/me/shedaniel/rei/gui/RecipeDisplayExporter.java index 3d9b98081..fe6007d1b 100644 --- a/src/main/java/me/shedaniel/rei/gui/RecipeDisplayExporter.java +++ b/src/main/java/me/shedaniel/rei/gui/RecipeDisplayExporter.java @@ -23,7 +23,6 @@ package me.shedaniel.rei.gui; -import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.gui.toast.ExportRecipeIdentifierToast; @@ -36,7 +35,7 @@ import net.minecraft.client.resource.language.I18n; import net.minecraft.client.texture.NativeImage; import net.minecraft.client.util.Window; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.resource.ResourceImpl; +import net.minecraft.util.Util; import org.jetbrains.annotations.ApiStatus; import java.io.File; @@ -105,7 +104,7 @@ public final class RecipeDisplayExporter extends Widget { strippedImage.setPixelRgba(x, y, nativeImage.getPixelRgba(x + (int) (rectangle.x * window.getScaleFactor()), y + (int) (rectangle.y * window.getScaleFactor()))); } } - ResourceImpl.RESOURCE_IO_EXECUTOR.execute(() -> { + Util.method_27958().execute(() -> { try { File export = new File(minecraft.runDirectory, "rei_exports"); export.mkdirs(); diff --git a/src/main/java/me/shedaniel/rei/gui/WarningAndErrorScreen.java b/src/main/java/me/shedaniel/rei/gui/WarningAndErrorScreen.java index 4f0fadedc..a9baafcea 100644 --- a/src/main/java/me/shedaniel/rei/gui/WarningAndErrorScreen.java +++ b/src/main/java/me/shedaniel/rei/gui/WarningAndErrorScreen.java @@ -25,7 +25,6 @@ package me.shedaniel.rei.gui; import me.shedaniel.clothconfig2.gui.widget.DynamicNewSmoothScrollingEntryListWidget; import me.shedaniel.rei.RoughlyEnoughItemsState; -import net.minecraft.class_5348; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawableHelper; import net.minecraft.client.gui.screen.Screen; @@ -37,6 +36,7 @@ import net.minecraft.client.util.TextCollector; 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.Style; import net.minecraft.text.Text; import net.minecraft.util.Formatting; @@ -70,13 +70,13 @@ public class WarningAndErrorScreen extends Screen { } private void addText(Text string) { - for (class_5348 s : textRenderer.wrapStringToWidthAsList(string, width - 80)) { + for (StringRenderable s : textRenderer.wrapStringToWidthAsList(string, width - 80)) { listWidget.creditsAddEntry(new TextItem(s)); } } private void addLink(Text string, String link) { - for (class_5348 s : textRenderer.wrapStringToWidthAsList(string, width - 80)) { + for (StringRenderable s : textRenderer.wrapStringToWidthAsList(string, width - 80)) { listWidget.creditsAddEntry(new LinkItem(s, link)); } } @@ -214,9 +214,9 @@ public class WarningAndErrorScreen extends Screen { } private static class TextItem extends StringItem { - private class_5348 text; + private StringRenderable text; - public TextItem(class_5348 text) { + public TextItem(StringRenderable text) { this.text = text; } @@ -242,11 +242,11 @@ public class WarningAndErrorScreen extends Screen { } private class LinkItem extends StringItem { - private class_5348 text; + private StringRenderable text; private String link; private boolean contains; - public LinkItem(class_5348 text, String link) { + public LinkItem(StringRenderable text, String link) { this.text = text; this.link = link; } @@ -256,12 +256,12 @@ public class WarningAndErrorScreen extends Screen { contains = mouseX >= x && mouseX <= x + entryWidth && mouseY >= y && mouseY <= y + entryHeight; if (contains) { WarningAndErrorScreen.this.renderTooltip(matrices, new LiteralText("Click to open link."), mouseX, mouseY); - class_5348 underlined = text.visit(new class_5348.StyledVisitor() { + StringRenderable underlined = text.visit(new StringRenderable.StyledVisitor() { TextCollector collector = new TextCollector(); @Override - public Optional accept(Style style, String asString) { - collector.add(class_5348.method_29431(asString, style)); + public Optional accept(Style style, String asString) { + collector.add(StringRenderable.styled(asString, style)); return Optional.of(collector.getCombined()); } }, Style.EMPTY.withFormatting(Formatting.UNDERLINE)).orElse(text); diff --git a/src/main/java/me/shedaniel/rei/gui/config/AppearanceTheme.java b/src/main/java/me/shedaniel/rei/gui/config/AppearanceTheme.java new file mode 100644 index 000000000..43bf52eeb --- /dev/null +++ b/src/main/java/me/shedaniel/rei/gui/config/AppearanceTheme.java @@ -0,0 +1,40 @@ +/* + * 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; + +import me.shedaniel.clothconfig2.gui.entries.SelectionListEntry; +import net.minecraft.client.resource.language.I18n; +import org.jetbrains.annotations.NotNull; + +import java.util.Locale; + +public enum AppearanceTheme implements SelectionListEntry.Translatable { + LIGHT, + DARK; + + @Override + public @NotNull String getKey() { + return I18n.translate("config.roughlyenoughitems.theme." + name().toLowerCase(Locale.ROOT)); + } +} diff --git a/src/main/java/me/shedaniel/rei/gui/config/ConfigButtonPosition.java b/src/main/java/me/shedaniel/rei/gui/config/ConfigButtonPosition.java new file mode 100644 index 000000000..b07238fc9 --- /dev/null +++ b/src/main/java/me/shedaniel/rei/gui/config/ConfigButtonPosition.java @@ -0,0 +1,40 @@ +/* + * 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; + +import me.shedaniel.clothconfig2.gui.entries.SelectionListEntry; +import net.minecraft.client.resource.language.I18n; +import org.jetbrains.annotations.NotNull; + +import java.util.Locale; + +public enum ConfigButtonPosition implements SelectionListEntry.Translatable { + UPPER, + LOWER; + + @Override + public @NotNull String getKey() { + return I18n.translate("config.roughlyenoughitems.layout.configButtonLocation." + name().toLowerCase(Locale.ROOT)); + } +} diff --git a/src/main/java/me/shedaniel/rei/gui/config/DisplayPanelLocation.java b/src/main/java/me/shedaniel/rei/gui/config/DisplayPanelLocation.java new file mode 100644 index 000000000..a9022ff09 --- /dev/null +++ b/src/main/java/me/shedaniel/rei/gui/config/DisplayPanelLocation.java @@ -0,0 +1,40 @@ +/* + * 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; + +import me.shedaniel.clothconfig2.gui.entries.SelectionListEntry; +import net.minecraft.client.resource.language.I18n; +import org.jetbrains.annotations.NotNull; + +import java.util.Locale; + +public enum DisplayPanelLocation implements SelectionListEntry.Translatable { + LEFT, + RIGHT; + + @Override + public @NotNull String getKey() { + return I18n.translate("config.roughlyenoughitems.accessibility.displayPanelLocation." + name().toLowerCase(Locale.ROOT)); + } +} diff --git a/src/main/java/me/shedaniel/rei/gui/config/EntryPanelOrdering.java b/src/main/java/me/shedaniel/rei/gui/config/EntryPanelOrdering.java new file mode 100644 index 000000000..fb11df19a --- /dev/null +++ b/src/main/java/me/shedaniel/rei/gui/config/EntryPanelOrdering.java @@ -0,0 +1,45 @@ +/* + * 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; + +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Internal +public enum EntryPanelOrdering { + + REGISTRY("ordering.rei.registry"), + NAME("ordering.rei.name"), + GROUPS("ordering.rei.item_groups"); + + private String nameTranslationKey; + + EntryPanelOrdering(String nameTranslationKey) { + this.nameTranslationKey = nameTranslationKey; + } + + public String getNameTranslationKey() { + return nameTranslationKey; + } + +} diff --git a/src/main/java/me/shedaniel/rei/gui/config/EntryPanelOrderingConfig.java b/src/main/java/me/shedaniel/rei/gui/config/EntryPanelOrderingConfig.java new file mode 100644 index 000000000..d64e0cb08 --- /dev/null +++ b/src/main/java/me/shedaniel/rei/gui/config/EntryPanelOrderingConfig.java @@ -0,0 +1,63 @@ +/* + * 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; + +import net.minecraft.client.resource.language.I18n; +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Internal +public enum EntryPanelOrderingConfig { + REGISTRY_ASCENDING(EntryPanelOrdering.REGISTRY, true), + NAME_ASCENDING(EntryPanelOrdering.NAME, true), + GROUPS_ASCENDING(EntryPanelOrdering.GROUPS, true), + REGISTRY_DESCENDING(EntryPanelOrdering.REGISTRY, false), + NAME_DESCENDING(EntryPanelOrdering.NAME, false), + GROUPS_DESCENDING(EntryPanelOrdering.GROUPS, false); + + private EntryPanelOrdering ordering; + private boolean isAscending; + + EntryPanelOrderingConfig(EntryPanelOrdering ordering, boolean isAscending) { + this.ordering = ordering; + this.isAscending = isAscending; + } + + public static EntryPanelOrderingConfig from(EntryPanelOrdering ordering, boolean isAscending) { + int index = ordering.ordinal() + (isAscending ? 0 : 3); + return values()[index]; + } + + public EntryPanelOrdering getOrdering() { + return ordering; + } + + public boolean isAscending() { + return isAscending; + } + + @Override + public String toString() { + return I18n.translate("config.roughlyenoughitems.list_ordering_button", I18n.translate(getOrdering().getNameTranslationKey()), I18n.translate(isAscending ? "ordering.rei.ascending" : "ordering.rei.descending")); + } +} diff --git a/src/main/java/me/shedaniel/rei/gui/config/ItemListOrdering.java b/src/main/java/me/shedaniel/rei/gui/config/ItemListOrdering.java deleted file mode 100644 index 9ef4c366e..000000000 --- a/src/main/java/me/shedaniel/rei/gui/config/ItemListOrdering.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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; - -import org.jetbrains.annotations.ApiStatus; - -@ApiStatus.Internal -public enum ItemListOrdering { - - registry("ordering.rei.registry"), - name("ordering.rei.name"), - item_groups("ordering.rei.item_groups"); - - private String nameTranslationKey; - - ItemListOrdering(String nameTranslationKey) { - this.nameTranslationKey = nameTranslationKey; - } - - public String getNameTranslationKey() { - return nameTranslationKey; - } - -} diff --git a/src/main/java/me/shedaniel/rei/gui/config/ItemListOrderingConfig.java b/src/main/java/me/shedaniel/rei/gui/config/ItemListOrderingConfig.java deleted file mode 100644 index 1b1f0a89b..000000000 --- a/src/main/java/me/shedaniel/rei/gui/config/ItemListOrderingConfig.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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; - -import net.minecraft.client.resource.language.I18n; -import org.jetbrains.annotations.ApiStatus; - -@ApiStatus.Internal -public enum ItemListOrderingConfig { - REGISTRY_ASCENDING(ItemListOrdering.registry, true), - NAME_ASCENDING(ItemListOrdering.name, true), - GROUPS_ASCENDING(ItemListOrdering.item_groups, true), - REGISTRY_DESCENDING(ItemListOrdering.registry, false), - NAME_DESCENDING(ItemListOrdering.name, false), - GROUPS_DESCENDING(ItemListOrdering.item_groups, false); - - private ItemListOrdering ordering; - private boolean isAscending; - - ItemListOrderingConfig(ItemListOrdering ordering, boolean isAscending) { - this.ordering = ordering; - this.isAscending = isAscending; - } - - public static ItemListOrderingConfig from(ItemListOrdering ordering, boolean isAscending) { - int index = ordering.ordinal() + (isAscending ? 0 : 3); - return values()[index]; - } - - public ItemListOrdering getOrdering() { - return ordering; - } - - public boolean isAscending() { - return isAscending; - } - - @Override - public String toString() { - return I18n.translate("config.roughlyenoughitems.list_ordering_button", I18n.translate(getOrdering().getNameTranslationKey()), I18n.translate(isAscending ? "ordering.rei.ascending" : "ordering.rei.descending")); - } -} diff --git a/src/main/java/me/shedaniel/rei/gui/config/SearchFieldLocation.java b/src/main/java/me/shedaniel/rei/gui/config/SearchFieldLocation.java index 5b39e2150..6dd19316a 100644 --- a/src/main/java/me/shedaniel/rei/gui/config/SearchFieldLocation.java +++ b/src/main/java/me/shedaniel/rei/gui/config/SearchFieldLocation.java @@ -36,6 +36,6 @@ public enum SearchFieldLocation { @Override public String toString() { - return I18n.translate("config.roughlyenoughitems.searchFieldLocation.%s", name().toLowerCase(Locale.ROOT)); + return I18n.translate("config.roughlyenoughitems.layout.searchFieldLocation.%s", name().toLowerCase(Locale.ROOT)); } } 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 5b8306c3f..4aecdef6f 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 @@ -23,148 +23,43 @@ package me.shedaniel.rei.gui.config.entry; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import com.mojang.blaze3d.systems.RenderSystem; -import me.shedaniel.clothconfig2.ClothConfigInitializer; +import com.google.common.collect.ImmutableList; import me.shedaniel.clothconfig2.api.AbstractConfigListEntry; -import me.shedaniel.clothconfig2.api.ScrollingContainer; -import me.shedaniel.clothconfig2.gui.widget.DynamicEntryListWidget; -import me.shedaniel.clothconfig2.gui.widget.DynamicNewSmoothScrollingEntryListWidget; -import me.shedaniel.math.Point; -import me.shedaniel.math.Rectangle; -import me.shedaniel.math.impl.PointHelper; -import me.shedaniel.rei.api.ConfigObject; -import me.shedaniel.rei.api.EntryRegistry; import me.shedaniel.rei.api.EntryStack; -import me.shedaniel.rei.api.REIHelper; -import me.shedaniel.rei.api.widgets.Tooltip; -import me.shedaniel.rei.gui.OverlaySearchField; -import me.shedaniel.rei.gui.widget.EntryWidget; -import me.shedaniel.rei.impl.ScreenHelper; -import me.shedaniel.rei.impl.SearchArgument; -import me.shedaniel.rei.utils.CollectionUtils; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.Element; -import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.AbstractButtonWidget; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.util.NarratorManager; +import net.minecraft.client.util.Window; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.Text; import net.minecraft.text.TranslatableText; -import net.minecraft.util.math.MathHelper; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.Nullable; -import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.Set; import java.util.function.Consumer; -import static me.shedaniel.rei.gui.widget.EntryListWidget.entrySize; - @ApiStatus.Internal public class FilteringEntry extends AbstractConfigListEntry> { - protected List selected = Lists.newArrayList(); - protected final ScrollingContainer scrolling = new ScrollingContainer() { - @Override - public int getMaxScrollHeight() { - return MathHelper.ceil(entryStacks.size() / (innerBounds.width / (float) entrySize())) * entrySize() + 28; - } - - @Override - public Rectangle getBounds() { - return FilteringEntry.this.getBounds(); - } - - @Override - public int getScrollBarX() { - return getParent().right - 7; - } - }; - private Consumer> saveConsumer; - private List defaultValue; - private List configFiltered; - private Tooltip tooltip = null; - @SuppressWarnings("rawtypes") private DynamicEntryListWidget lastList = null; - private List entryStacks = null; - private Rectangle innerBounds; - private List entries = Collections.emptyList(); - private List elements = Collections.emptyList(); - - private Point selectionPoint = null; - private Point secondPoint = null; - - private OverlaySearchField searchField; - private ButtonWidget selectAllButton; - private ButtonWidget selectNoneButton; - private ButtonWidget hideButton; - private ButtonWidget showButton; - - private boolean edited = false; - - private List lastSearchArguments = Collections.emptyList(); - - public FilteringEntry(List configFiltered, List defaultValue, Consumer> saveConsumer) { + private int width; + Consumer> saveConsumer; + List defaultValue; + List configFiltered; + boolean edited = false; + private final FilteringScreen filteringScreen = new FilteringScreen(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); + }); + private final List children = ImmutableList.of(buttonWidget); + + public FilteringEntry(int width, List configFiltered, List defaultValue, Consumer> saveConsumer) { super(NarratorManager.EMPTY, false); + this.width = width; this.configFiltered = configFiltered; this.defaultValue = defaultValue; this.saveConsumer = saveConsumer; - this.searchField = new OverlaySearchField(0, 0, 0, 0); - { - Text selectAllText = new TranslatableText("config.roughlyenoughitems.filteredEntries.selectAll"); - this.selectAllButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getWidth(selectAllText) + 10, 20, selectAllText, button -> { - this.selectionPoint = new Point(-Integer.MAX_VALUE / 2, -Integer.MAX_VALUE / 2); - this.secondPoint = new Point(Integer.MAX_VALUE / 2, Integer.MAX_VALUE / 2); - }); - } - { - Text selectNoneText = new TranslatableText("config.roughlyenoughitems.filteredEntries.selectNone"); - this.selectNoneButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getWidth(selectNoneText) + 10, 20, selectNoneText, button -> { - this.selectionPoint = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE); - this.secondPoint = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE); - }); - } - { - Text hideText = new TranslatableText("config.roughlyenoughitems.filteredEntries.hide"); - this.hideButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getWidth(hideText) + 10, 20, hideText, button -> { - 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); - if (entry.isSelected() && !entry.isFiltered()) { - configFiltered.add(stack); - edited = true; - } - } - }); - } - { - Text showText = new TranslatableText("config.roughlyenoughitems.filteredEntries.show"); - this.showButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getWidth(showText) + 10, 20, showText, button -> { - 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); - if (entry.isSelected() && configFiltered.remove(stack)) { - edited = true; - } - } - }); - } - this.searchField.isMain = false; - } - - private static Rectangle updateInnerBounds(Rectangle bounds) { - int width = Math.max(MathHelper.floor((bounds.width - 2 - 6) / (float) entrySize()), 1); - return new Rectangle((int) (bounds.getCenterX() - width * entrySize() / 2f), bounds.y + 5, width * entrySize(), bounds.height); - } - - @SuppressWarnings("rawtypes") - public Rectangle getBounds() { - DynamicEntryListWidget listWidget = getParent(); - return new Rectangle(listWidget.left, listWidget.top, listWidget.right - listWidget.left, listWidget.bottom - listWidget.top); } @Override @@ -183,286 +78,23 @@ public class FilteringEntry extends AbstractConfigListEntry> { this.edited = false; } - @Override - public boolean isEdited() { - return super.isEdited() || edited; - } - - @SuppressWarnings("rawtypes") @Override public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) { - DynamicEntryListWidget parent = getParent(); - Rectangle bounds = getBounds(); - if (lastList != parent) { - updateSearch(this.searchField.getText()); - lastList = parent; - this.searchField.getBounds().setBounds(bounds.getCenterX() - 75, bounds.getMaxY() - 22, 150, 18); - this.selectAllButton.x = 2; - this.selectAllButton.y = bounds.getMaxY() - 22; - this.selectNoneButton.x = 4 + selectAllButton.getWidth(); - this.selectNoneButton.y = bounds.getMaxY() - 22; - this.hideButton.x = bounds.getMaxX() - hideButton.getWidth() - showButton.getWidth() - 4; - this.hideButton.y = bounds.getMaxY() - 22; - this.showButton.x = bounds.getMaxX() - showButton.getWidth() - 2; - this.showButton.y = bounds.getMaxY() - 22; - this.searchField.setChangedListener(this::updateSearch); - } - tooltip = null; - if (bounds.isEmpty()) - return; - for (EntryListEntry entry : entries) - entry.clearStacks(); - int skip = Math.max(0, MathHelper.floor(scrolling.scrollAmount / (float) entrySize())); - int nextIndex = skip * innerBounds.width / entrySize(); - int i = nextIndex; - for (; i < entryStacks.size(); i++) { - EntryStack stack = entryStacks.get(i); - EntryListEntry entry = entries.get(nextIndex); - entry.getBounds().y = (int) (entry.backupY - scrolling.scrollAmount); - if (entry.getBounds().y > bounds.getMaxY()) - break; - entry.entry(stack); - entry.render(matrices, mouseX, mouseY, delta); - nextIndex++; - } - updatePosition(delta); - scrolling.renderScrollBar(0xff000000, 1, REIHelper.getInstance().isDarkThemeEnabled() ? 0.8f : 1f); - matrices.push(); - matrices.translate(0, 0, 300); - this.searchField.laterRender(matrices, mouseX, mouseY, delta); - this.selectAllButton.render(matrices, mouseX, mouseY, delta); - this.selectNoneButton.render(matrices, mouseX, mouseY, delta); - this.hideButton.render(matrices, mouseX, mouseY, delta); - this.showButton.render(matrices, mouseX, mouseY, delta); - matrices.pop(); - if (tooltip != null) { - ScreenHelper.getLastOverlay().renderTooltip(matrices, tooltip); - } - } - - private Rectangle getSelection() { - if (selectionPoint != null) { - Point p = secondPoint; - if (p == null) { - p = PointHelper.ofMouse(); - p.translate(0, (int) scrolling.scrollAmount); - } - 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); - return new Rectangle(left, (int) (top - scrolling.scrollAmount), right - left, bottom - top); - } - return new Rectangle(0, 0, 0, 0); - } - - @Override - public boolean mouseDragged(double mouseX, double mouseY, int button, double dx, double dy) { - if (scrolling.mouseDragged(mouseX, mouseY, button, dx, dy, ConfigObject.getInstance().doesSnapToRows(), entrySize())) - return true; - return super.mouseDragged(mouseX, mouseY, button, dx, dy); - } - - 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); - } - - public void updateSearch(String searchTerm) { - lastSearchArguments = SearchArgument.processSearchTerm(searchTerm); - Set list = Sets.newLinkedHashSet(); - for (EntryStack stack : EntryRegistry.getInstance().getStacksList()) { - if (canLastSearchTermsBeAppliedTo(stack)) { - list.add(stack.copy().setting(EntryStack.Settings.CHECK_AMOUNT, EntryStack.Settings.FALSE).setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE).setting(EntryStack.Settings.CHECK_TAGS, EntryStack.Settings.TRUE)); - } - } - - entryStacks = Lists.newArrayList(list); - updateEntriesPosition(); - } - - public boolean canLastSearchTermsBeAppliedTo(EntryStack stack) { - return lastSearchArguments.isEmpty() || SearchArgument.canSearchTermsBeAppliedTo(stack, lastSearchArguments); - } - - public void updateEntriesPosition() { - this.innerBounds = updateInnerBounds(getBounds()); - int width = innerBounds.width / entrySize(); - int pageHeight = innerBounds.height / entrySize(); - int slotsToPrepare = Math.max(entryStacks.size() * 3, width * pageHeight * 3); - int currentX = 0; - int currentY = 0; - List entries = Lists.newArrayList(); - for (int i = 0; i < slotsToPrepare; i++) { - int xPos = currentX * entrySize() + innerBounds.x; - int yPos = currentY * entrySize() + innerBounds.y; - entries.add(new EntryListEntry(xPos, yPos)); - currentX++; - if (currentX >= width) { - currentX = 0; - currentY++; - } - } - this.entries = entries; - this.elements = Lists.newArrayList(entries); - this.elements.add(searchField); + Window window = MinecraftClient.getInstance().getWindow(); + this.buttonWidget.active = this.isEditable(); + this.buttonWidget.y = y; + this.buttonWidget.x = x + entryWidth / 2 - width / 2; + this.buttonWidget.setWidth(width); + this.buttonWidget.render(matrices, mouseX, mouseY, delta); } @Override public List children() { - return elements; - } - - @Override - public boolean mouseClicked(double double_1, double double_2, int int_1) { - if (scrolling.updateDraggingState(double_1, double_2, int_1)) - return true; - - if (getBounds().contains(double_1, double_2)) { - if (searchField.mouseClicked(double_1, double_2, int_1)) { - this.selectionPoint = null; - this.secondPoint = null; - return true; - } else if (selectAllButton.mouseClicked(double_1, double_2, int_1)) { - return true; - } else if (selectNoneButton.mouseClicked(double_1, double_2, int_1)) { - return true; - } else if (hideButton.mouseClicked(double_1, double_2, int_1)) { - return true; - } else if (showButton.mouseClicked(double_1, double_2, int_1)) { - return true; - } - if (int_1 == 0) { - this.selectionPoint = new Point(double_1, double_2 + scrolling.scrollAmount); - this.secondPoint = null; - return true; - } - } - return false; - } - - @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); - if (secondPoint.equals(selectionPoint)) { - secondPoint.translate(1, 1); - } - return true; - } - return super.mouseReleased(mouseX, mouseY, button); + return children; } @Override - public boolean charTyped(char chr, int keyCode) { - for (Element element : children()) - if (element.charTyped(chr, keyCode)) - return true; - return super.charTyped(chr, keyCode); - } - - @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - for (Element element : children()) - if (element.keyPressed(keyCode, scanCode, modifiers)) - return true; - if (Screen.isSelectAll(keyCode)) { - this.selectionPoint = new Point(0, 0); - this.secondPoint = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE); - return true; - } - return false; - } - - public void updateArea(@Nullable String searchTerm) { - if (searchTerm != null) - updateSearch(searchTerm); - else if (entryStacks == null) - updateSearch(""); - else - updateEntriesPosition(); - } - - @Override - public boolean mouseScrolled(double double_1, double double_2, double double_3) { - if (getBounds().contains(double_1, double_2)) { - scrolling.offset(ClothConfigInitializer.getScrollStep() * -double_3, true); - return true; - } - super.mouseScrolled(double_1, double_2, double_3); - return true; - } - - private class EntryListEntry extends EntryWidget { - private int backupY; - - private EntryListEntry(int x, int y) { - super(new Point(x, y)); - this.backupY = y; - getBounds().width = getBounds().height = entrySize(); - interactableFavorites(false); - interactable(false); - noHighlight(); - } - - @Override - public boolean containsMouse(double mouseX, double mouseY) { - return super.containsMouse(mouseX, mouseY) && FilteringEntry.this.getBounds().contains(mouseX, mouseY); - } - - @Override - protected void drawHighlighted(MatrixStack matrices, int mouseX, int mouseY, float delta) { - - } - - @Override - public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { - super.render(matrices, mouseX, mouseY, delta); - if (isSelected()) { - Rectangle bounds = getBounds(); - RenderSystem.disableDepthTest(); - fillGradient(matrices, bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), 0x896b70fa, 0x896b70fa); - RenderSystem.enableDepthTest(); - } - } - - @Override - public EntryStack getCurrentEntry() { - return super.getCurrentEntry(); - } - - public boolean isSelected() { - return getSelection().intersects(getBounds()); - } - - public boolean isFiltered() { - return CollectionUtils.findFirstOrNullEqualsEntryIgnoreAmount(configFiltered, getCurrentEntry()) != null; - } - - @Override - protected void drawBackground(MatrixStack matrices, int mouseX, int mouseY, float delta) { - if (isFiltered()) { - Rectangle bounds = getBounds(); - RenderSystem.disableDepthTest(); - fillGradient(matrices, bounds.x, bounds.y, bounds.getMaxX(), bounds.getMaxY(), 0xffff0000, 0xffff0000); - RenderSystem.enableDepthTest(); - } - } - - @Override - protected void queueTooltip(MatrixStack matrices, int mouseX, int mouseY, float delta) { - if (searchField.containsMouse(mouseX, mouseY)) - return; - Tooltip tooltip = getCurrentTooltip(new Point(mouseX, mouseY)); - if (tooltip != null) { - FilteringEntry.this.tooltip = tooltip; - } - } + public boolean isEdited() { + return super.isEdited() || edited; } } diff --git a/src/main/java/me/shedaniel/rei/gui/config/entry/FilteringScreen.java b/src/main/java/me/shedaniel/rei/gui/config/entry/FilteringScreen.java new file mode 100644 index 000000000..61b8c9d0a --- /dev/null +++ b/src/main/java/me/shedaniel/rei/gui/config/entry/FilteringScreen.java @@ -0,0 +1,510 @@ +/* + * 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 com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.mojang.blaze3d.systems.RenderSystem; +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.math.Point; +import me.shedaniel.math.Rectangle; +import me.shedaniel.math.impl.PointHelper; +import me.shedaniel.rei.api.ConfigObject; +import me.shedaniel.rei.api.EntryRegistry; +import me.shedaniel.rei.api.EntryStack; +import me.shedaniel.rei.api.REIHelper; +import me.shedaniel.rei.api.widgets.Tooltip; +import me.shedaniel.rei.gui.OverlaySearchField; +import me.shedaniel.rei.gui.widget.EntryWidget; +import me.shedaniel.rei.impl.ScreenHelper; +import me.shedaniel.rei.impl.SearchArgument; +import me.shedaniel.rei.utils.CollectionUtils; +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.render.BufferBuilder; +import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.util.NarratorManager; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.LiteralText; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Matrix4f; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import static me.shedaniel.rei.gui.widget.EntryListWidget.entrySize; + +@ApiStatus.Internal +public class FilteringScreen extends Screen { + protected List selected = Lists.newArrayList(); + protected final ScrollingContainer scrolling = new ScrollingContainer() { + @Override + public int getMaxScrollHeight() { + return MathHelper.ceil(entryStacks.size() / (innerBounds.width / (float) entrySize())) * entrySize() + 28; + } + + @Override + public Rectangle getBounds() { + return FilteringScreen.this.getBounds(); + } + + @Override + public int getScrollBarX() { + return width - 7; + } + }; + + Screen parent; + private FilteringEntry filteringEntry; + private Tooltip tooltip = null; + private List entryStacks = null; + private Rectangle innerBounds; + private List entries = Collections.emptyList(); + private List elements = Collections.emptyList(); + + private Point selectionPoint = null; + private Point secondPoint = null; + + private OverlaySearchField searchField; + private ButtonWidget selectAllButton; + private ButtonWidget selectNoneButton; + private ButtonWidget hideButton; + private ButtonWidget showButton; + private ButtonWidget backButton; + + private List lastSearchArguments = Collections.emptyList(); + + public FilteringScreen(FilteringEntry filteringEntry) { + super(new TranslatableText("config.roughlyenoughitems.filteringScreen")); + this.filteringEntry = filteringEntry; + this.searchField = new OverlaySearchField(0, 0, 0, 0); + { + Text selectAllText = new TranslatableText("config.roughlyenoughitems.filteredEntries.selectAll"); + this.selectAllButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getWidth(selectAllText) + 10, 20, selectAllText, button -> { + this.selectionPoint = new Point(-Integer.MAX_VALUE / 2, -Integer.MAX_VALUE / 2); + this.secondPoint = new Point(Integer.MAX_VALUE / 2, Integer.MAX_VALUE / 2); + }); + } + { + Text selectNoneText = new TranslatableText("config.roughlyenoughitems.filteredEntries.selectNone"); + this.selectNoneButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getWidth(selectNoneText) + 10, 20, selectNoneText, button -> { + this.selectionPoint = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE); + this.secondPoint = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE); + }); + } + { + Text hideText = new TranslatableText("config.roughlyenoughitems.filteredEntries.hide"); + this.hideButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getWidth(hideText) + 10, 20, hideText, button -> { + 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); + if (entry.isSelected() && !entry.isFiltered()) { + filteringEntry.configFiltered.add(stack); + filteringEntry.edited = true; + } + } + }); + } + { + Text showText = new TranslatableText("config.roughlyenoughitems.filteredEntries.show"); + this.showButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getWidth(showText) + 10, 20, showText, button -> { + 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); + if (entry.isSelected() && filteringEntry.configFiltered.remove(stack)) { + filteringEntry.edited = true; + } + } + }); + } + { + Text backText = new LiteralText("↩ ").append(new TranslatableText("gui.back")); + this.backButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.getWidth(backText) + 10, 20, backText, button -> { + client.openScreen(parent); + this.parent = null; + }); + } + this.searchField.isMain = false; + } + + private static Rectangle updateInnerBounds(Rectangle bounds) { + int width = Math.max(MathHelper.floor((bounds.width - 2 - 6) / (float) entrySize()), 1); + return new Rectangle((int) (bounds.getCenterX() - width * entrySize() / 2f), bounds.y + 5, width * entrySize(), bounds.height); + } + + public Rectangle getBounds() { + return new Rectangle(0, 30, width, this.height - 30); + } + + @Override + protected void init() { + super.init(); + Rectangle bounds = getBounds(); + updateSearch(this.searchField.getText()); + this.searchField.getBounds().setBounds(bounds.getCenterX() - 75, bounds.getMaxY() - 22, 150, 18); + this.selectAllButton.x = 2; + this.selectAllButton.y = bounds.getMaxY() - 22; + this.selectNoneButton.x = 4 + selectAllButton.getWidth(); + this.selectNoneButton.y = bounds.getMaxY() - 22; + this.hideButton.x = bounds.getMaxX() - hideButton.getWidth() - showButton.getWidth() - 4; + this.hideButton.y = bounds.getMaxY() - 22; + this.showButton.x = bounds.getMaxX() - showButton.getWidth() - 2; + this.showButton.y = bounds.getMaxY() - 22; + this.backButton.x = 4; + this.backButton.y = 4; + this.searchField.setChangedListener(this::updateSearch); + } + + protected void renderHoleBackground(MatrixStack matrices, int y1, int y2, int tint, int alpha1, int alpha2) { + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder buffer = tessellator.getBuffer(); + this.client.getTextureManager().bindTexture(BACKGROUND_TEXTURE); + Matrix4f matrix = matrices.peek().getModel(); + RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); + float float_1 = 32.0F; + buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR); + buffer.vertex(matrix, 0, y2, 0.0F).texture(0.0F, y2 / 32.0F).color(tint, tint, tint, alpha2).next(); + buffer.vertex(matrix, this.width, y2, 0.0F).texture(this.width / 32.0F, y2 / 32.0F).color(tint, tint, tint, alpha2).next(); + buffer.vertex(matrix, this.width, y1, 0.0F).texture(this.width / 32.0F, y1 / 32.0F).color(tint, tint, tint, alpha1).next(); + buffer.vertex(matrix, 0, y1, 0.0F).texture(0.0F, y1 / 32.0F).color(tint, tint, tint, alpha1).next(); + tessellator.draw(); + } + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + renderHoleBackground(matrices, 0, height, 32, 255, 255); + Rectangle bounds = getBounds(); + tooltip = null; + if (bounds.isEmpty()) + return; + ScissorsHandler.INSTANCE.scissor(bounds); + for (EntryListEntry entry : entries) + entry.clearStacks(); + int skip = Math.max(0, MathHelper.floor(scrolling.scrollAmount / (float) entrySize())); + int nextIndex = skip * innerBounds.width / entrySize(); + int i = nextIndex; + for (; i < entryStacks.size(); i++) { + EntryStack stack = entryStacks.get(i); + EntryListEntry entry = entries.get(nextIndex); + entry.getBounds().y = (int) (entry.backupY - scrolling.scrollAmount); + if (entry.getBounds().y > bounds.getMaxY()) + break; + entry.entry(stack); + entry.render(matrices, mouseX, mouseY, delta); + nextIndex++; + } + updatePosition(delta); + scrolling.renderScrollBar(0xff000000, 1, REIHelper.getInstance().isDarkThemeEnabled() ? 0.8f : 1f); + matrices.push(); + matrices.translate(0, 0, 300); + this.searchField.laterRender(matrices, mouseX, mouseY, delta); + this.selectAllButton.render(matrices, mouseX, mouseY, delta); + this.selectNoneButton.render(matrices, mouseX, mouseY, delta); + this.hideButton.render(matrices, mouseX, mouseY, delta); + this.showButton.render(matrices, mouseX, mouseY, delta); + matrices.pop(); + + ScissorsHandler.INSTANCE.removeLastScissor(); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder buffer = tessellator.getBuffer(); + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate(770, 771, 0, 1); + RenderSystem.disableAlphaTest(); + RenderSystem.shadeModel(7425); + RenderSystem.disableTexture(); + Matrix4f matrix = matrices.peek().getModel(); + buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR); + buffer.vertex(matrix, 0, bounds.y + 4, 0.0F).texture(0.0F, 1.0F).color(0, 0, 0, 0).next(); + buffer.vertex(matrix, width, bounds.y + 4, 0.0F).texture(1.0F, 1.0F).color(0, 0, 0, 0).next(); + buffer.vertex(matrix, width, bounds.y, 0.0F).texture(1.0F, 0.0F).color(0, 0, 0, 255).next(); + buffer.vertex(matrix, 0, bounds.y, 0.0F).texture(0.0F, 0.0F).color(0, 0, 0, 255).next(); + tessellator.draw(); + RenderSystem.enableTexture(); + RenderSystem.shadeModel(7424); + RenderSystem.enableAlphaTest(); + RenderSystem.disableBlend(); + renderHoleBackground(matrices, 0, bounds.y, 64, 255, 255); + + this.backButton.render(matrices, mouseX, mouseY, delta); + + if (tooltip != null) { + ScreenHelper.getLastOverlay().renderTooltip(matrices, tooltip); + } + + this.textRenderer.drawWithShadow(matrices, this.title, this.width / 2.0F - this.textRenderer.getWidth(this.title) / 2.0F, 12.0F, -1); + } + + private Rectangle getSelection() { + if (selectionPoint != null) { + Point p = secondPoint; + if (p == null) { + p = PointHelper.ofMouse(); + p.translate(0, (int) scrolling.scrollAmount); + } + 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); + return new Rectangle(left, (int) (top - scrolling.scrollAmount), right - left, bottom - top); + } + return new Rectangle(0, 0, 0, 0); + } + + @Override + public boolean mouseDragged(double mouseX, double mouseY, int button, double dx, double dy) { +