diff options
| author | shedaniel <daniel@shedaniel.me> | 2022-06-26 21:45:36 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2023-05-29 21:06:47 +0800 |
| commit | 30557360a886875b5e953d32ac577706ede3c8e2 (patch) | |
| tree | 334ec0c96db4194a45c4d17c6c8ff11838250496 /default-plugin/src/main/java | |
| parent | 14d3f79a9df125525956660b3bdda594005ef653 (diff) | |
| download | RoughlyEnoughItems-30557360a886875b5e953d32ac577706ede3c8e2.tar.gz RoughlyEnoughItems-30557360a886875b5e953d32ac577706ede3c8e2.tar.bz2 RoughlyEnoughItems-30557360a886875b5e953d32ac577706ede3c8e2.zip | |
Primitive tags category implementation
Diffstat (limited to 'default-plugin/src/main/java')
9 files changed, 455 insertions, 51 deletions
diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/DefaultTagCategory.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/DefaultTagCategory.java index 07d5fe985..49ebb91ca 100644 --- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/DefaultTagCategory.java +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/DefaultTagCategory.java @@ -26,7 +26,7 @@ package me.shedaniel.rei.plugin.client.categories.tag; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.gui.Renderer; -import me.shedaniel.rei.api.client.gui.widgets.DelegateWidget; +import me.shedaniel.rei.api.client.gui.widgets.DelegateWidgetWithBounds; import me.shedaniel.rei.api.client.gui.widgets.Widget; import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds; import me.shedaniel.rei.api.client.gui.widgets.Widgets; @@ -38,8 +38,6 @@ import me.shedaniel.rei.plugin.common.displays.tag.DefaultTagDisplay; import me.shedaniel.rei.plugin.common.displays.tag.TagNode; import me.shedaniel.rei.plugin.common.displays.tag.TagNodes; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiComponent; -import net.minecraft.core.Registry; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TranslatableComponent; @@ -73,39 +71,31 @@ public class DefaultTagCategory implements DisplayCategory<DefaultTagDisplay<?, Rectangle innerBounds = new Rectangle(bounds.x + 6 + 14, bounds.y + 6, bounds.width - 12 - 14, bounds.height - 12); widgets.add(Widgets.createSlotBase(innerBounds)); - Widget[] delegate = new Widget[]{Widgets.noOp()}; + WidgetWithBounds[] delegate = new WidgetWithBounds[]{Widgets.noOp()}; TagNode<?>[] tagNode = new TagNode[]{null}; Rectangle overflowBounds = new Rectangle(innerBounds.x + 1, innerBounds.y + 1, innerBounds.width - 2, innerBounds.height - 2); - WidgetWithBounds inner = Widgets.withBounds(new DelegateWidget(Widgets.noOp()) { + widgets.add(Widgets.withTranslate(Widgets.overflowed(overflowBounds, new DelegateWidgetWithBounds(Widgets.noOp(), Rectangle::new) { @Override - protected Widget delegate() { + protected WidgetWithBounds delegate() { return delegate[0]; } - }, overflowBounds); - widgets.add(Widgets.withTranslate(Widgets.overflowed(overflowBounds, Widgets.withBounds(Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> { - new GuiComponent() { - { - fillGradient(matrices, 0, 0, 1000, 1000, 0xff3489eb, 0xffc41868); - for (int x = 0; x < 10; x++) { - for (int y = 0; y < 10; y++) { - Widgets.createSlot(new Point(500 - 9 * 10 + x * 18, 500 - 9 * 10 + y * 18)) - .entry(EntryStacks.of(Registry.ITEM.byId(x + y * 10 + 1))) - .disableBackground() - .render(matrices, mouseX, mouseY, delta); - } - } - } - }; - }), new Rectangle(0, 0, 1000, 1000))), 0, 0, 20)); + + @Override + public Rectangle getBounds() { + return delegate().getBounds(); + } + }), 0, 0, 20)); TagNodes.create(display.getKey(), dataResult -> { if (dataResult.error().isPresent()) { - delegate[0] = Widgets.concat( + delegate[0] = Widgets.withBounds(Widgets.concat( Widgets.createLabel(new Point(innerBounds.getCenterX(), innerBounds.getCenterY() - 8), new TextComponent("Failed to resolve tags!")), Widgets.createLabel(new Point(innerBounds.getCenterX(), innerBounds.getCenterY() - 8), new TextComponent(dataResult.error().get().message())) - ); + ), overflowBounds); } else { tagNode[0] = dataResult.result().get(); + //noinspection rawtypes + delegate[0] = Widgets.padded(16, new TagTreeWidget(tagNode[0], display.getMapper())); } }); diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/ReferenceTagNodeWidget.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/ReferenceTagNodeWidget.java new file mode 100644 index 000000000..75beaf41c --- /dev/null +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/ReferenceTagNodeWidget.java @@ -0,0 +1,83 @@ +/* + * 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.plugin.client.categories.tag; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.widgets.Slot; +import me.shedaniel.rei.api.client.gui.widgets.Tooltip; +import me.shedaniel.rei.api.client.gui.widgets.Widgets; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.util.EntryIngredients; +import me.shedaniel.rei.plugin.common.displays.tag.TagNode; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.core.Holder; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.resources.ResourceLocation; + +import java.util.Collections; +import java.util.List; +import java.util.function.Function; + +public class ReferenceTagNodeWidget<S, T> extends TagNodeWidget<S, T> { + private final TagNode<S> node; + private final Rectangle bounds; + private final Slot slot; + private final List<? extends GuiEventListener> children; + + public ReferenceTagNodeWidget(TagNode<S> node, Function<Holder<S>, EntryStack<T>> mapper) { + this.node = node; + this.bounds = new Rectangle(0, 0, 24, 23); + this.slot = Widgets.createSlot(new Rectangle(0, 0, 18, 18)) + .disableBackground() + .disableHighlight() + .disableTooltips() + .entries(EntryIngredients.ofTag(node.getReference(), mapper)); + this.children = Collections.singletonList(this.slot); + } + + @Override + public Rectangle getBounds() { + return bounds; + } + + @Override + public void render(PoseStack poses, int mouseX, int mouseY, float delta) { + RenderSystem.setShader(GameRenderer::getPositionTexShader); + RenderSystem.setShaderTexture(0, new ResourceLocation("textures/gui/advancements/widgets.png")); + this.blit(poses, bounds.x, bounds.y, 1, 128 + 27, 24, 24); + this.slot.getBounds().setLocation(bounds.getCenterX() - this.slot.getBounds().getWidth() / 2, bounds.y + (bounds.height - this.slot.getBounds().getHeight()) / 2 + 1); + this.slot.render(poses, mouseX, mouseY, delta); + if (this.containsMouse(mouseX, mouseY)) { + Tooltip.create(new TextComponent("#" + this.node.getReference().location().toString())).queue(); + } + } + + @Override + public List<? extends GuiEventListener> children() { + return children; + } +} diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/TagNodeWidget.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/TagNodeWidget.java new file mode 100644 index 000000000..9f2216935 --- /dev/null +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/TagNodeWidget.java @@ -0,0 +1,43 @@ +/* + * 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.plugin.client.categories.tag; + +import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.plugin.common.displays.tag.TagNode; +import net.minecraft.core.Holder; + +import java.util.function.Function; + +public abstract class TagNodeWidget<S, T> extends WidgetWithBounds { + static <S, T> TagNodeWidget<S, T> create(TagNode<S> node, Function<Holder<S>, EntryStack<T>> mapper) { + if (node.getReference() != null) { + return new ReferenceTagNodeWidget<>(node, mapper); + } else if (node.getValue() != null) { + return new ValueTagNodeWidget<>(node, mapper); + } else { + throw new IllegalArgumentException("TagNode has no value or reference"); + } + } +} diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/TagTreeWidget.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/TagTreeWidget.java new file mode 100644 index 000000000..f544d4d7f --- /dev/null +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/TagTreeWidget.java @@ -0,0 +1,122 @@ +/* + * 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.plugin.client.categories.tag; + +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.math.Color; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.plugin.common.displays.tag.TagNode; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.core.Holder; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Stream; + +public class TagTreeWidget<S, T> extends WidgetWithBounds { + private final Rectangle bounds; + private final TagNode<S> node; + private final TagNodeWidget<S, T> rootWidget; + private final List<TagTreeWidget<S, T>> childWidgets; + private final List<WidgetWithBounds> children; + + public TagTreeWidget(TagNode<S> node, Function<Holder<S>, EntryStack<T>> mapper) { + this.node = node; + this.rootWidget = TagNodeWidget.create(node, mapper); + this.childWidgets = new ArrayList<>(); + for (TagNode<S> childNode : node.children()) { + TagTreeWidget<S, T> childWidget = new TagTreeWidget<>(childNode, mapper); + childWidget.getBounds().y = rootWidget.getBounds().getMaxY() + 16; + this.childWidgets.add(childWidget); + } + int childrenTotalWidth = childWidgets.stream().map(WidgetWithBounds::getBounds).mapToInt(value -> value.width + 6).sum() - 6; + int x = 0; + for (TagTreeWidget<S, T> childWidget : this.childWidgets) { + childWidget.getBounds().x = rootWidget.getBounds().getCenterX() - childrenTotalWidth / 2 + x; + x += childWidget.getBounds().width + 6; + } + this.children = Stream.concat(Stream.of(this.rootWidget), this.childWidgets.stream()).toList(); + this.bounds = new Rectangle(this.children.stream() + .map(WidgetWithBounds::getBounds) + .reduce(Rectangle::union) + .orElse(new Rectangle()) + .getSize()); + } + + @Override + public Rectangle getBounds() { + return bounds; + } + + @Override + public void render(PoseStack poses, int mouseX, int mouseY, float delta) { + this.rootWidget.getBounds().setLocation(getBounds().getCenterX() - this.rootWidget.getBounds().getWidth() / 2, + getBounds().y); + this.rootWidget.render(poses, mouseX, mouseY, delta); + if (childWidgets.isEmpty()) return; + vLine(poses, rootWidget.getBounds().getCenterX(), rootWidget.getBounds().getMaxY(), rootWidget.getBounds().getMaxY() + 6, 0xFFFFFFFF); + int childrenTotalWidth = childWidgets.stream().map(WidgetWithBounds::getBounds).mapToInt(value -> value.width + 6).sum() - 6; + hLine(poses, rootWidget.getBounds().getCenterX() - childrenTotalWidth / 2 + childWidgets.get(0).getBounds().width / 2, + rootWidget.getBounds().getCenterX() + childrenTotalWidth / 2 - childWidgets.get(childWidgets.size() - 1).getBounds().width / 2, + rootWidget.getBounds().getMaxY() + 6, 0xFFFFFFFF); + int x = 0; + for (TagTreeWidget<S, T> childWidget : this.childWidgets) { + vLine(poses, getBounds().getCenterX() - childrenTotalWidth / 2 + x + childWidget.getBounds().width / 2, + rootWidget.getBounds().getMaxY() + 6, rootWidget.getBounds().getMaxY() + 16, 0xFFFFFFFF); + childWidget.getBounds().setLocation(getBounds().getCenterX() - childrenTotalWidth / 2 + x, + this.rootWidget.getBounds().getMaxY() + 16); + childWidget.render(poses, mouseX, mouseY, delta); + x += childWidget.getBounds().width + 6; + } + } + + @Override + public List<? extends GuiEventListener> children() { + return children; + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + return super.mouseClicked(mouseX, mouseY, button); + } + + @Override + public boolean mouseReleased(double mouseX, double mouseY, int button) { + for (GuiEventListener element : children()) + if (element.mouseReleased(mouseX, mouseY, button)) + return true; + return false; + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + for (GuiEventListener element : children()) + if (element.keyPressed(keyCode, scanCode, modifiers)) + return true; + return false; + } +} diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/TagTreesWidget.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/TagTreesWidget.java new file mode 100644 index 000000000..bfa0a0e56 --- /dev/null +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/TagTreesWidget.java @@ -0,0 +1,48 @@ +/* + * 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.plugin.client.categories.tag; + +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds; +import net.minecraft.client.gui.components.events.GuiEventListener; + +import java.util.List; + +public class TagTreesWidget extends WidgetWithBounds { + @Override + public Rectangle getBounds() { + return null; + } + + @Override + public void render(PoseStack poses, int mouseX, int mouseY, float delta) { + + } + + @Override + public List<? extends GuiEventListener> children() { + return null; + } +} diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/ValueTagNodeWidget.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/ValueTagNodeWidget.java new file mode 100644 index 000000000..677c4cd1d --- /dev/null +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/tag/ValueTagNodeWidget.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.plugin.client.categories.tag; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Matrix4f; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.widgets.*; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.util.EntryIngredients; +import me.shedaniel.rei.plugin.common.displays.tag.TagNode; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderSet; +import net.minecraft.util.Mth; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.function.Function; + +public class ValueTagNodeWidget<S, T> extends TagNodeWidget<S, T> { + private final Rectangle bounds; + private final WidgetWithBounds widget; + private final List<? extends GuiEventListener> children; + + public ValueTagNodeWidget(TagNode<S> node, Function<Holder<S>, EntryStack<T>> mapper) { + HolderSet<S> holders = node.getValue(); + int width = Math.min(4, holders.size()); + int height = Math.max((int) Math.ceil(holders.size() * 1.0 / width), 1); + this.bounds = new Rectangle(0, 0, 16 * width + 12, 16 * height + 12); + Panel background = Widgets.createRecipeBase(bounds.clone()); + Panel slotBackground = Widgets.createSlotBase(new Rectangle(5, 5, 16 * width + 2, 16 * height + 2)); + int i = 0; + List<Widget> widgets = new ArrayList<>(); + widgets.add(background); + widgets.add(slotBackground); + for (Holder<S> holder : holders) { + int x = i % width; + int y = i / width; + Slot slot = Widgets.createSlot(new Rectangle(x * 16 + 5, y * 16 + 5, 18, 18)) + .entry(mapper.apply(holder)) + .disableBackground(); + widgets.add(slot); + i++; + } + this.widget = Widgets.withTranslate(Widgets.concat(widgets), + $ -> Matrix4f.createTranslateMatrix(getBounds().x, getBounds().y, 0)); + this.children = Collections.singletonList(this.widget); + } + + @Override + public Rectangle getBounds() { + return bounds; + } + + @Override + public void render(PoseStack poses, int mouseX, int mouseY, float delta) { + this.widget.render(poses, mouseX, mouseY, delta); + } + + @Override + public List<? extends GuiEventListener> children() { + return children; + } + + @Override + public boolean mouseReleased(double mouseX, double mouseY, int button) { + for (GuiEventListener element : children()) + if (element.mouseReleased(mouseX, mouseY, button)) + return true; + return false; + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + for (GuiEventListener element : children()) + if (element.keyPressed(keyCode, scanCode, modifiers)) + return true; + return false; + } +} diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/tag/DefaultTagDisplay.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/tag/DefaultTagDisplay.java index 09c453019..6b070eded 100644 --- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/tag/DefaultTagDisplay.java +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/tag/DefaultTagDisplay.java @@ -95,4 +95,8 @@ public class DefaultTagDisplay<S, T> implements Display { public TagKey<S> getKey() { return key; } + + public Function<Holder<S>, EntryStack<T>> getMapper() { + return mapper; + } } diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/tag/TagNode.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/tag/TagNode.java index 94b5b047d..2dc2d0265 100644 --- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/tag/TagNode.java +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/tag/TagNode.java @@ -24,14 +24,14 @@ package me.shedaniel.rei.plugin.common.displays.tag; import net.minecraft.core.Holder; +import net.minecraft.core.HolderSet; import net.minecraft.resources.ResourceKey; import net.minecraft.tags.TagKey; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; @ApiStatus.Internal public abstract class TagNode<T> { @@ -41,8 +41,8 @@ public abstract class TagNode<T> { this.children = new ArrayList<>(); } - public static <T> TagNode<T> ofValue(Holder<T> value) { - return new ValueTagNode<>(value); + public static <T> TagNode<T> ofValues(HolderSet<T> value) { + return new ValuesTagNode<>(value); } public static <T> TagNode<T> ofReference(TagKey<T> key) { @@ -57,8 +57,8 @@ public abstract class TagNode<T> { children.add(child); } - public void addValueChild(Holder<T> child) { - children.add(ofValue(child)); + public void addValuesChild(HolderSet<T> child) { + children.add(ofValues(child)); } public void addReferenceChild(TagKey<T> child) { @@ -66,29 +66,27 @@ public abstract class TagNode<T> { } public String asTree() { - StringBuilder buffer = new StringBuilder(50); - printTree(buffer, "", ""); - return buffer.toString(); + StringBuilder builder = new StringBuilder(50); + printTree(builder, "", ""); + return builder.toString(); } - private void printTree(StringBuilder buffer, String prefix, String childrenPrefix) { - buffer.append(prefix); - buffer.append(asText()); - buffer.append('\n'); + private void printTree(StringBuilder builder, String prefix, String childrenPrefix) { + asText(prefix, builder); for (Iterator<TagNode<T>> it = children.iterator(); it.hasNext(); ) { TagNode<T> next = it.next(); if (it.hasNext()) { - next.printTree(buffer, childrenPrefix + "├── ", childrenPrefix + "│ "); + next.printTree(builder, childrenPrefix + "├── ", childrenPrefix + "│ "); } else { - next.printTree(buffer, childrenPrefix + "└── ", childrenPrefix + " "); + next.printTree(builder, childrenPrefix + "└── ", childrenPrefix + " "); } } } - protected abstract String asText(); + protected abstract void asText(String prefix, StringBuilder builder); @Nullable - public Holder<T> getValue() { + public HolderSet<T> getValue() { return null; } @@ -97,21 +95,27 @@ public abstract class TagNode<T> { return null; } - private static class ValueTagNode<T> extends TagNode<T> { - private final Holder<T> value; + private static class ValuesTagNode<T> extends TagNode<T> { + private final HolderSet<T> value; - public ValueTagNode(Holder<T> value) { + public ValuesTagNode(HolderSet<T> value) { this.value = value; } @Override - public Holder<T> getValue() { + public HolderSet<T> getValue() { return value; } @Override - protected String asText() { - return value.unwrapKey().map(ResourceKey::location).orElse(null) + ""; + protected void asText(String prefix, StringBuilder builder) { + for (Holder<T> holder : value) { + holder.unwrapKey().ifPresent(key -> { + builder.append(prefix); + builder.append(key.location().toString()); + builder.append('\n'); + }); + } } } @@ -128,8 +132,10 @@ public abstract class TagNode<T> { } @Override - protected String asText() { - return key.location() + ""; + protected void asText(String prefix, StringBuilder builder) { + builder.append(prefix); + builder.append(key.location()); + builder.append('\n'); } } } diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/tag/TagNodes.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/tag/TagNodes.java index 832249cc2..163776b87 100644 --- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/tag/TagNodes.java +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/common/displays/tag/TagNodes.java @@ -36,6 +36,7 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Minecraft; import net.minecraft.core.Holder; +import net.minecraft.core.HolderSet; import net.minecraft.core.Registry; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceKey; @@ -187,12 +188,16 @@ public class TagNodes { if (tagData == null) return DataResult.error("Tag Missing: " + tagKey.location()); TagNode<T> self = TagNode.ofReference(tagKey); + List<Holder<T>> holders = new ArrayList<>(); for (int element : tagData.otherElements()) { Optional<Holder<T>> holder = registry.getHolder(element); if (holder.isPresent()) { - self.addValueChild(holder.get()); + holders.add(holder.get()); } } + if (!holders.isEmpty()) { + self.addValuesChild(HolderSet.direct(holders)); + } for (ResourceLocation childTagId : tagData.otherTags()) { TagKey<T> childTagKey = TagKey.create(tagKey.registry(), childTagId); if (registry.getTag(childTagKey).isPresent()) { |
