aboutsummaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2022-04-22 15:47:18 +0800
committershedaniel <daniel@shedaniel.me>2022-04-22 15:47:18 +0800
commitca88276257bfccf055d03dcfce8df6b43ca40bf9 (patch)
tree7ee656ab7a3a94a2cc15af07f56bd970300de586 /runtime
parente3ab358e5fe608414629f4e214b1ec8f856dbe2d (diff)
parent8eb903cc67d5e6813570ddd1d74bcfd3a3ffba45 (diff)
downloadRoughlyEnoughItems-ca88276257bfccf055d03dcfce8df6b43ca40bf9.tar.gz
RoughlyEnoughItems-ca88276257bfccf055d03dcfce8df6b43ca40bf9.tar.bz2
RoughlyEnoughItems-ca88276257bfccf055d03dcfce8df6b43ca40bf9.zip
Merge remote-tracking branch 'origin/8.x-1.18.2' into 9.x-1.19
Diffstat (limited to 'runtime')
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRuleOptionsScreen.java122
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java83
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/DelegateWidgetWithTranslate.java86
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/InternalWidgets.java83
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/MergedWidget.java66
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/RendererWrappedWidget.java72
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/VanillaWrappedWidget.java82
-rw-r--r--runtime/src/main/resources/assets/roughlyenoughitems/lang/de_de.json50
-rwxr-xr-xruntime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json3
-rw-r--r--runtime/src/main/resources/assets/roughlyenoughitems/lang/pt_br.json57
-rw-r--r--runtime/src/main/resources/assets/roughlyenoughitems/lang/zh_cn.json4
-rw-r--r--runtime/src/main/resources/assets/roughlyenoughitems/lang/zh_tw.json4
-rw-r--r--runtime/src/main/resources/assets/roughlyenoughitems/textures/gui/shapeless_icon_1x.pngbin0 -> 138 bytes
-rw-r--r--runtime/src/main/resources/assets/roughlyenoughitems/textures/gui/shapeless_icon_2x.pngbin0 -> 209 bytes
-rw-r--r--runtime/src/main/resources/assets/roughlyenoughitems/textures/gui/shapeless_icon_3x.pngbin0 -> 267 bytes
-rw-r--r--runtime/src/main/resources/assets/roughlyenoughitems/textures/gui/shapeless_icon_4x.pngbin0 -> 341 bytes
16 files changed, 646 insertions, 66 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRuleOptionsScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRuleOptionsScreen.java
index 154c34445..fac731ecf 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRuleOptionsScreen.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRuleOptionsScreen.java
@@ -23,8 +23,12 @@
package me.shedaniel.rei.impl.client.config.entries;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import me.shedaniel.clothconfig2.gui.widget.DynamicElementListWidget;
+import me.shedaniel.math.Rectangle;
import me.shedaniel.rei.impl.client.entry.filtering.FilteringRule;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.Button;
@@ -32,16 +36,21 @@ import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.narration.NarratableEntry;
import net.minecraft.client.gui.screens.Screen;
+import net.minecraft.client.resources.sounds.SimpleSoundInstance;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.FormattedText;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
+import net.minecraft.sounds.SoundEvents;
import net.minecraft.util.FormattedCharSequence;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
+import java.util.function.Supplier;
public abstract class FilteringRuleOptionsScreen<T extends FilteringRule<?>> extends Screen {
private final FilteringEntry entry;
@@ -258,4 +267,117 @@ public abstract class FilteringRuleOptionsScreen<T extends FilteringRule<?>> ext
return Collections.singletonList(widget);
}
}
+
+ public static class SubRulesEntry extends RuleEntry {
+ private static final ResourceLocation CONFIG_TEX = new ResourceLocation("cloth-config2", "textures/gui/cloth_config.png");
+ private final CategoryLabelWidget widget;
+ private final List<RuleEntry> rules;
+ private final List<GuiEventListener> children;
+ private boolean expanded;
+ private Supplier<Component> name;
+
+ public SubRulesEntry(FilteringRule<?> rule, Supplier<Component> name, List<RuleEntry> rules) {
+ super(rule);
+ this.rules = rules;
+ this.widget = new CategoryLabelWidget();
+ this.name = name;
+ this.expanded = true;
+ this.children = new ArrayList<>(rules);
+ this.children.add(widget);
+ }
+
+ public List<RuleEntry> getRules() {
+ return rules;
+ }
+
+ @Override
+ public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) {
+ RenderSystem.setShaderTexture(0, CONFIG_TEX);
+ RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
+ this.widget.rectangle.x = x + 3;
+ this.widget.rectangle.y = y;
+ this.widget.rectangle.width = entryWidth - 6;
+ this.widget.rectangle.height = 24;
+ this.blit(matrices, x + 3, y + 5, 24, (this.widget.rectangle.contains(mouseX, mouseY) ? 18 : 0) + (this.expanded ? 9 : 0), 9, 9);
+ Minecraft.getInstance().font.drawShadow(matrices, this.name.get().getVisualOrderText(), (float) x + 3 + 15, (float) (y + 6), this.widget.rectangle.contains(mouseX, mouseY) ? -1638890 : -1);
+
+ for (RuleEntry performanceEntry : this.rules) {
+ performanceEntry.setParent(this.getParent());
+ }
+
+ if (this.expanded) {
+ int yy = y + 24;
+
+ RuleEntry entry;
+ for (Iterator<RuleEntry> iterator = this.rules.iterator(); iterator.hasNext(); yy += entry.getItemHeight()) {
+ entry = iterator.next();
+ entry.render(matrices, -1, yy, x + 3 + 15, entryWidth - 15 - 3, entry.getItemHeight(), mouseX, mouseY, isHovered && this.getFocused() == entry, delta);
+ }
+ }
+ }
+
+ @Override
+ public int getMorePossibleHeight() {
+ if (!this.expanded) {
+ return -1;
+ } else {
+ List<Integer> list = new ArrayList<>();
+ int i = 24;
+
+ for (RuleEntry entry : this.rules) {
+ i += entry.getItemHeight();
+ if (entry.getMorePossibleHeight() >= 0) {
+ list.add(i + entry.getMorePossibleHeight());
+ }
+ }
+
+ list.add(i);
+ return list.stream().max(Integer::compare).orElse(0) - this.getItemHeight();
+ }
+ }
+
+ @Override
+ public int getItemHeight() {
+ if (!this.expanded) {
+ return 24;
+ } else {
+ int i = 24;
+
+ RuleEntry entry;
+ for (Iterator<RuleEntry> iterator = this.rules.iterator(); iterator.hasNext(); i += entry.getItemHeight()) {
+ entry = iterator.next();
+ }
+
+ return i;
+ }
+ }
+
+ @Override
+ public List<? extends GuiEventListener> children() {
+ return children;
+ }
+
+ @Override
+ public List<? extends NarratableEntry> narratables() {
+ return Collections.emptyList();
+ }
+
+ public class CategoryLabelWidget implements GuiEventListener {
+ private final Rectangle rectangle = new Rectangle();
+
+ public CategoryLabelWidget() {
+ }
+
+ @Override
+ public boolean mouseClicked(double mouseX, double mouseY, int button) {
+ if (this.rectangle.contains(mouseX, mouseY)) {
+ SubRulesEntry.this.expanded = !SubRulesEntry.this.expanded;
+ Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+ }
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java
index 5f5969674..0e48f1b97 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java
@@ -25,35 +25,49 @@ package me.shedaniel.rei.impl.client.entry.filtering.rules;
import com.google.common.base.Suppliers;
import com.google.common.collect.Lists;
+import com.mojang.blaze3d.vertex.PoseStack;
+import me.shedaniel.clothconfig2.api.ScissorsHandler;
+import me.shedaniel.math.Rectangle;
+import me.shedaniel.rei.api.client.REIRuntime;
+import me.shedaniel.rei.api.client.registry.entry.EntryRegistry;
import me.shedaniel.rei.api.client.search.SearchFilter;
import me.shedaniel.rei.api.client.search.SearchProvider;
import me.shedaniel.rei.api.common.entry.EntryStack;
import me.shedaniel.rei.api.common.util.CollectionUtils;
import me.shedaniel.rei.impl.client.config.entries.FilteringEntry;
import me.shedaniel.rei.impl.client.config.entries.FilteringRuleOptionsScreen;
+import me.shedaniel.rei.impl.client.config.entries.FilteringScreen;
import me.shedaniel.rei.impl.client.entry.filtering.AbstractFilteringRule;
import me.shedaniel.rei.impl.client.entry.filtering.FilteringCache;
import me.shedaniel.rei.impl.client.entry.filtering.FilteringContext;
import me.shedaniel.rei.impl.client.entry.filtering.FilteringResult;
+import me.shedaniel.rei.impl.client.gui.widget.BatchedEntryRendererManager;
+import me.shedaniel.rei.impl.client.gui.widget.EntryWidget;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.ChatFormatting;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+import net.minecraft.client.gui.narration.NarratableEntry;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
+import net.minecraft.util.Mth;
import net.minecraft.util.StringUtil;
-import java.util.Collection;
-import java.util.List;
-import java.util.Optional;
+import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.BiFunction;
import java.util.function.Consumer;
+import java.util.function.Function;
import java.util.function.Supplier;
+import java.util.stream.Collectors;
+
+import static me.shedaniel.rei.impl.client.gui.widget.EntryListWidget.entrySize;
@Environment(EnvType.CLIENT)
public class SearchFilteringRule extends AbstractFilteringRule<SearchFilteringRule> {
@@ -115,7 +129,7 @@ public class SearchFilteringRule extends AbstractFilteringRule<SearchFilteringRu
@Override
public SearchFilteringRule createNew() {
- return new SearchFilteringRule("", true);
+ return new SearchFilteringRule("", false);
}
private void processList(Collection<EntryStack<?>> stacks, List<CompletableFuture<List<EntryStack<?>>>> completableFutures) {
@@ -147,21 +161,34 @@ public class SearchFilteringRule extends AbstractFilteringRule<SearchFilteringRu
return Optional.of((entry, screen) -> new FilteringRuleOptionsScreen<SearchFilteringRule>(entry, this, screen) {
TextFieldRuleEntry entry = null;
BooleanRuleEntry show = null;
-
+ List<EntryWidget> entryStacks = new ArrayList<>();
+
@Override
public void addEntries(Consumer<RuleEntry> entryConsumer) {
addEmpty(entryConsumer, 10);
addText(entryConsumer, new TranslatableComponent("rule.roughlyenoughitems.filtering.search.filter").withStyle(ChatFormatting.GRAY));
entryConsumer.accept(entry = new TextFieldRuleEntry(width - 36, rule, widget -> {
widget.setMaxLength(9999);
+ widget.setResponder(searchTerm -> {
+ SearchFilter filter = SearchProvider.getInstance().createFilter(searchTerm);
+ entryStacks = EntryRegistry.getInstance().getEntryStacks().parallel()
+ .filter(filter)
+ .map(EntryStack::normalize)
+ .map(stack -> new EntryWidget(new Rectangle(0, 0, 18,18)).noBackground().entry(stack))
+ .collect(Collectors.toList());
+ });
if (entry != null) widget.setValue(entry.getWidget().getValue());
else widget.setValue(rule.filterStr);
}));
addEmpty(entryConsumer, 10);
addText(entryConsumer, new TranslatableComponent("rule.roughlyenoughitems.filtering.search.show").withStyle(ChatFormatting.GRAY));
- entryConsumer.accept(show = new BooleanRuleEntry(width - 36, show == null ? rule.show : show.getBoolean(), rule, bool -> {
+ Function<Boolean, Component> function = bool -> {
return new TranslatableComponent("rule.roughlyenoughitems.filtering.search.show." + bool);
- }));
+ };
+ entryConsumer.accept(show = new BooleanRuleEntry(width - 36, show == null ? rule.show : show.getBoolean(), rule, function));
+ addEmpty(entryConsumer, 10);
+ entryConsumer.accept(new SubRulesEntry(rule, () -> function.apply(show == null ? rule.show : show.getBoolean()),
+ Collections.singletonList(new EntryStacksRuleEntry(rule, () -> entryStacks, entry, show))));
}
@Override
@@ -171,4 +198,46 @@ public class SearchFilteringRule extends AbstractFilteringRule<SearchFilteringRu
}
});
}
+
+ public static class EntryStacksRuleEntry extends FilteringRuleOptionsScreen.RuleEntry {
+ private final Supplier<List<EntryWidget>> entryStacks;
+ private int totalHeight;
+
+ public EntryStacksRuleEntry(SearchFilteringRule rule, Supplier<List<EntryWidget>> entryStacks, FilteringRuleOptionsScreen.TextFieldRuleEntry entry, FilteringRuleOptionsScreen.BooleanRuleEntry show) {
+ super(rule);
+ this.entryStacks = entryStacks;
+ }
+
+ @Override
+ public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) {
+ BatchedEntryRendererManager manager = new BatchedEntryRendererManager();
+ int entrySize = entrySize();
+ int width = entryWidth / entrySize;
+ int i = 0;
+ for (EntryWidget stack : entryStacks.get()) {
+ stack.getBounds().setLocation(x + (i % width) * entrySize, y + (i / width) * entrySize);
+ if (stack.getBounds().getMaxY() >= 0 && stack.getBounds().getY() <= Minecraft.getInstance().getWindow().getGuiScaledHeight()) {
+ manager.add(stack);
+ }
+ i++;
+ }
+ manager.render(matrices, mouseX, mouseY, delta);
+ totalHeight = (i / width + 1) * entrySize;
+ }
+
+ @Override
+ public int getItemHeight() {
+ return totalHeight;
+ }
+
+ @Override
+ public List<? extends NarratableEntry> narratables() {
+ return Lists.newArrayList();
+ }
+
+ @Override
+ public List<? extends GuiEventListener> children() {
+ return Lists.newArrayList();
+ }
+ }
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/DelegateWidgetWithTranslate.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/DelegateWidgetWithTranslate.java
new file mode 100644
index 000000000..5867f4232
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/DelegateWidgetWithTranslate.java
@@ -0,0 +1,86 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.impl.client.gui.widget;
+
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.math.Matrix4f;
+import com.mojang.math.Vector4f;
+import me.shedaniel.rei.api.client.gui.widgets.DelegateWidget;
+import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds;
+
+import java.util.function.Supplier;
+
+public class DelegateWidgetWithTranslate extends DelegateWidget {
+ private final Supplier<Matrix4f> translate;
+
+ public DelegateWidgetWithTranslate(WidgetWithBounds widget, Supplier<Matrix4f> translate) {
+ super(widget);
+ this.translate = translate;
+ }
+
+ @Override
+ public void render(PoseStack poseStack, int i, int j, float f) {
+ poseStack.pushPose();
+ poseStack.last().pose().multiply(translate.get());
+ Vector4f mouse = transformMouse(i, j);
+ super.render(poseStack, (int) mouse.x(), (int) mouse.y(), f);
+ poseStack.popPose();
+ }
+
+ private Vector4f transformMouse(double mouseX, double mouseY) {
+ Vector4f mouse = new Vector4f((float) mouseX, (float) mouseY, 0, 1);
+ mouse.transform(translate.get());
+ return mouse;
+ }
+
+ @Override
+ public boolean containsMouse(double mouseX, double mouseY) {
+ Vector4f mouse = transformMouse(mouseX, mouseY);
+ return super.containsMouse(mouse.x(), mouse.y());
+ }
+
+ @Override
+ public boolean mouseClicked(double d, double e, int i) {
+ Vector4f mouse = transformMouse(d, e);
+ return super.mouseClicked(mouse.x(), mouse.y(), i);
+ }
+
+ @Override
+ public boolean mouseReleased(double d, double e, int i) {
+ Vector4f mouse = transformMouse(d, e);
+ return super.mouseReleased(mouse.x(), mouse.y(), i);
+ }
+
+ @Override
+ public boolean mouseDragged(double d, double e, int i, double f, double g) {
+ Vector4f mouse = transformMouse(d, e);
+ return super.mouseDragged(mouse.x(), mouse.y(), i, f, g);
+ }
+
+ @Override
+ public boolean mouseScrolled(double d, double e, double f) {
+ Vector4f mouse = transformMouse(d, e);
+ return super.mouseScrolled(mouse.x(), mouse.y(), f);
+ }
+} \ No newline at end of file
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/InternalWidgets.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/InternalWidgets.java
index e39b48fc5..f757bf9ad 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/InternalWidgets.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/InternalWidgets.java
@@ -23,13 +23,14 @@
package me.shedaniel.rei.impl.client.gui.widget;
-import com.google.common.collect.Lists;
import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.math.Matrix4f;
import me.shedaniel.math.Point;
import me.shedaniel.math.Rectangle;
import me.shedaniel.math.impl.PointHelper;
import me.shedaniel.rei.api.client.config.ConfigObject;
import me.shedaniel.rei.api.client.gui.DrawableConsumer;
+import me.shedaniel.rei.api.client.gui.Renderer;
import me.shedaniel.rei.api.client.gui.widgets.*;
import me.shedaniel.rei.api.client.registry.display.DisplayCategory;
import me.shedaniel.rei.api.common.display.Display;
@@ -44,12 +45,12 @@ import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.FormattedText;
+import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.ApiStatus;
import java.util.Collection;
import java.util.List;
-import java.util.Objects;
import java.util.function.Supplier;
@ApiStatus.Internal
@@ -141,34 +142,8 @@ public final class InternalWidgets {
return new MergedWidget(widget2, widget1);
}
- private static class MergedWidget extends Widget {
- private final List<Widget> widgets;
-
- public MergedWidget(Widget widget1, Widget widget2) {
- this.widgets = Lists.newArrayList(Objects.requireNonNull(widget1), Objects.requireNonNull(widget2));
- }
-
- @Override
- public void render(PoseStack matrices, int mouseX, int mouseY, float delta) {
- for (Widget widget : widgets) {
- widget.setZ(getZ());
- widget.render(matrices, mouseX, mouseY, delta);
- }
- }
-
- @Override
- public List<? extends GuiEventListener> children() {
- return widgets;
- }
-
- @Override
- public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
- for (Widget widget : this.widgets) {
- if (widget.mouseScrolled(mouseX, mouseY, amount))
- return true;
- }
- return false;
- }
+ public static Widget concatWidgets(List<Widget> widgets) {
+ return new MergedWidget(widgets);
}
private static class LateRenderableWidget extends DelegateWidget implements LateRenderable {
@@ -188,17 +163,33 @@ public final class InternalWidgets {
}
@Override
+ public Widget wrapVanillaWidget(GuiEventListener element) {
+ if (element instanceof Widget) return (Widget) element;
+ return new VanillaWrappedWidget(element);
+ }
+
+ @Override
+ public WidgetWithBounds wrapRenderer(Supplier<Rectangle> bounds, Renderer renderer) {
+ return new RendererWrappedWidget(renderer, bounds);
+ }
+
+ @Override
+ public WidgetWithBounds withTranslate(WidgetWithBounds widget, Supplier<Matrix4f> translate) {
+ return new DelegateWidgetWithTranslate(widget, translate);
+ }
+
+ @Override
public Widget createDrawableWidget(DrawableConsumer drawable) {
return new DrawableWidget(drawable);
}
@Override
- public me.shedaniel.rei.api.client.gui.widgets.Slot createSlot(Point point) {
+ public Slot createSlot(Point point) {
return new EntryWidget(point);
}
@Override
- public me.shedaniel.rei.api.client.gui.widgets.Slot createSlot(Rectangle bounds) {
+ public Slot createSlot(Rectangle bounds) {
return new EntryWidget(bounds);
}
@@ -236,5 +227,33 @@ public final class InternalWidgets {
public DrawableConsumer createFillRectangleConsumer(Rectangle rectangle, int color) {
return new FillRectangleDrawableConsumer(rectangle, color);
}
+
+ @Override
+ public Widget createShapelessIcon(Point point) {
+ int magnification;
+ double scale = Minecraft.getInstance().getWindow().getGuiScale();
+ if (scale >= 1 && scale <= 4 && scale == Math.floor(scale)) {
+ magnification = (int) scale;
+ } else if (scale > 4 && scale == Math.floor(scale)) {
+ magnification = 1;
+ for (int i = 4; i >= 1; i--) {
+ if (scale % i == 0) {
+ magnification = i;
+ break;
+ }
+ }
+ } else {
+ magnification = 4;
+ }
+ Rectangle bounds = new Rectangle(point.getX() - 9, point.getY() + 1, 8, 8);
+ Widget widget = Widgets.createTexturedWidget(new ResourceLocation("roughlyenoughitems:textures/gui/shapeless_icon_" + magnification + "x.png"), bounds.getX(), bounds.getY(), 0, 0, bounds.getWidth(), bounds.getHeight(), 1, 1, 1, 1);
+ return Widgets.withTooltip(Widgets.withBounds(widget, bounds),
+ new TranslatableComponent("text.rei.shapeless"));
+ }
+
+ @Override
+ public Widget concatWidgets(List<Widget> widgets) {
+ return InternalWidgets.concatWidgets(widgets);
+ }
}
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/MergedWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/MergedWidget.java
new file mode 100644
index 000000000..e419a7db7
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/MergedWidget.java
@@ -0,0 +1,66 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.impl.client.gui.widget;
+
+import com.google.common.collect.Lists;
+import com.mojang.blaze3d.vertex.PoseStack;
+import me.shedaniel.rei.api.client.gui.widgets.Widget;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+
+import java.util.List;
+import java.util.Objects;
+
+public class MergedWidget extends Widget {
+ private final List<Widget> widgets;
+
+ public MergedWidget(Widget widget1, Widget widget2) {
+ this.widgets = Lists.newArrayList(Objects.requireNonNull(widget1), Objects.requireNonNull(widget2));
+ }
+
+ public MergedWidget(List<Widget> widgets) {
+ this.widgets = widgets;
+ }
+
+ @Override
+ public void render(PoseStack matrices, int mouseX, int mouseY, float delta) {
+ for (Widget widget : widgets) {
+ widget.setZ(getZ());
+ widget.render(matrices, mouseX, mouseY, delta);
+ }
+ }
+
+ @Override
+ public List<? extends GuiEventListener> children() {
+ return widgets;
+ }
+
+ @Override
+ public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
+ for (Widget widget : this.widgets) {
+ if (widget.mouseScrolled(mouseX, mouseY, amount))
+ return true;
+ }
+ return false;
+ }
+} \ No newline at end of file
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/RendererWrappedWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/RendererWrappedWidget.java
new file mode 100644
index 000000000..97d9f3e3d
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/RendererWrappedWidget.java
@@ -0,0 +1,72 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.impl.client.gui.widget;
+
+import com.mojang.blaze3d.vertex.PoseStack;
+import me.shedaniel.math.Rectangle;
+import me.shedaniel.rei.api.client.gui.Renderer;
+import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds;
+import net.minecraft.client.gui.components.events.GuiEventListener;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Supplier;
+
+public class RendererWrappedWidget extends WidgetWithBounds {
+ private final Renderer renderer;
+ private final Supplier<Rectangle> bounds;
+
+ public RendererWrappedWidget(Renderer renderer, Supplier<Rectangle> bounds) {
+ this.renderer = Objects.requireNonNull(renderer);
+ this.bounds = Objects.requireNonNull(bounds);
+ }
+
+ @Override
+ public void render(PoseStack matrices, int mouseX, int mouseY, float delta) {
+ renderer.render(matrices, getBounds(), mouseX, mouseY, delta);
+ }
+
+ @Override
+ public List<? extends GuiEventListener> children() {
+ if (renderer instanceof GuiEventListener listener)
+ return Collections.singletonList(listener);
+ return Collections.emptyList();
+ }
+
+ @Override
+ public void setZ(int z) {
+ renderer.setZ(z);
+ }
+
+ @Override
+ public int getZ() {
+ return renderer.getZ();
+ }
+
+ @Override
+ public Rectangle getBounds() {
+ return bounds.get();
+ }
+} \ No newline at end of file
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/VanillaWrappedWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/VanillaWrappedWidget.java
new file mode 100644
index 000000000..2aacd5e73
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/VanillaWrappedWidget.java
@@ -0,0 +1,82 @@
+/*
+ * 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,