diff options
| author | shedaniel <daniel@shedaniel.me> | 2022-06-26 21:45:36 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2022-06-28 03:21:12 +0800 |
| commit | 74e4781b57b2f6e0aa581bce0f68ae2ab0de363b (patch) | |
| tree | 16774826e4969952f1af56426f80b4032e9af1ac /default-plugin/src/main/java/me/shedaniel/rei/plugin/client | |
| parent | 87ccf96bf8a7705da7844dce9b94364b2e3d1b25 (diff) | |
| download | RoughlyEnoughItems-74e4781b57b2f6e0aa581bce0f68ae2ab0de363b.tar.gz RoughlyEnoughItems-74e4781b57b2f6e0aa581bce0f68ae2ab0de363b.tar.bz2 RoughlyEnoughItems-74e4781b57b2f6e0aa581bce0f68ae2ab0de363b.zip | |
Primitive tags category implementation
Diffstat (limited to 'default-plugin/src/main/java/me/shedaniel/rei/plugin/client')
6 files changed, 413 insertions, 24 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; + } +} |
