From b41ea249ad2af3c2d03bb269bf4eb7b03220fdb8 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Thu, 14 Apr 2022 12:50:23 +0800 Subject: Add what's getting hidden in the search filtering screen --- .../config/entries/FilteringRuleOptionsScreen.java | 122 +++++++++++++++++++++ .../entry/filtering/rules/SearchFilteringRule.java | 83 ++++++++++++-- 2 files changed, 198 insertions(+), 7 deletions(-) (limited to 'runtime') 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> extends Screen { private final FilteringEntry entry; @@ -258,4 +267,117 @@ public abstract class FilteringRuleOptionsScreen> 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 rules; + private final List children; + private boolean expanded; + private Supplier name; + + public SubRulesEntry(FilteringRule rule, Supplier name, List 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 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 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 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 iterator = this.rules.iterator(); iterator.hasNext(); i += entry.getItemHeight()) { + entry = iterator.next(); + } + + return i; + } + } + + @Override + public List children() { + return children; + } + + @Override + public List 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 { @@ -115,7 +129,7 @@ public class SearchFilteringRule extends AbstractFilteringRule> stacks, List>>> completableFutures) { @@ -147,21 +161,34 @@ public class SearchFilteringRule extends AbstractFilteringRule new FilteringRuleOptionsScreen(entry, this, screen) { TextFieldRuleEntry entry = null; BooleanRuleEntry show = null; - + List entryStacks = new ArrayList<>(); + @Override public void addEntries(Consumer 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 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> entryStacks; + private int totalHeight; + + public EntryStacksRuleEntry(SearchFilteringRule rule, Supplier> 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 narratables() { + return Lists.newArrayList(); + } + + @Override + public List children() { + return Lists.newArrayList(); + } + } } -- cgit From ad476378effa1dfd5fbef9c4d4cb5eadb9954d32 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sat, 16 Apr 2022 03:15:46 +0800 Subject: Add shapeless indicator --- .../gui/widget/DelegateWidgetWithTranslate.java | 86 ++++++++++++++++++++++ .../impl/client/gui/widget/InternalWidgets.java | 83 +++++++++++++-------- .../rei/impl/client/gui/widget/MergedWidget.java | 66 +++++++++++++++++ .../client/gui/widget/RendererWrappedWidget.java | 72 ++++++++++++++++++ .../client/gui/widget/VanillaWrappedWidget.java | 82 +++++++++++++++++++++ .../assets/roughlyenoughitems/lang/de_de.json | 50 +++++++++++++ .../assets/roughlyenoughitems/lang/en_us.json | 3 +- .../assets/roughlyenoughitems/lang/pt_br.json | 57 ++++++++------ .../assets/roughlyenoughitems/lang/zh_cn.json | 4 +- .../assets/roughlyenoughitems/lang/zh_tw.json | 4 +- 10 files changed, 448 insertions(+), 59 deletions(-) create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/DelegateWidgetWithTranslate.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/MergedWidget.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/RendererWrappedWidget.java create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/VanillaWrappedWidget.java (limited to 'runtime') 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 translate; + + public DelegateWidgetWithTranslate(WidgetWithBounds widget, Supplier 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 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 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 widgets) { + return new MergedWidget(widgets); } private static class LateRenderableWidget extends DelegateWidget implements LateRenderable { @@ -187,18 +162,34 @@ public final class InternalWidgets { return PanelWidget.isRendering(panel); } + @Override + public Widget wrapVanillaWidget(GuiEventListener element) { + if (element instanceof Widget) return (Widget) element; + return new VanillaWrappedWidget(element); + } + + @Override + public WidgetWithBounds wrapRenderer(Supplier bounds, Renderer renderer) { + return new RendererWrappedWidget(renderer, bounds); + } + + @Override + public WidgetWithBounds withTranslate(WidgetWithBounds widget, Supplier 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 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 widgets; + + public MergedWidget(Widget widget1, Widget widget2) { + this.widgets = Lists.newArrayList(Objects.requireNonNull(widget1), Objects.requireNonNull(widget2)); + } + + public MergedWidget(List 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 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 bounds; + + public RendererWrappedWidget(Renderer renderer, Supplier 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 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, 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.rei.api.client.gui.widgets.Widget; +import net.minecraft.client.gui.GuiComponent; +import net.minecraft.client.gui.components.events.ContainerEventHandler; +import net.minecraft.client.gui.components.events.GuiEventListener; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +public class VanillaWrappedWidget extends Widget { + private GuiEventListener element; + + public VanillaWrappedWidget(GuiEventListener element) { + this.element = Objects.requireNonNull(element); + setFocused(element); + } + + @Override + public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { + if (element instanceof GuiComponent component) + component.setBlitOffset(getZ()); + if (element instanceof net.minecraft.client.gui.components.Widget widget) + widget.render(matrices, mouseX, mouseY, delta); + } + + @Override + public List children() { + return Collections.singletonList(element); + } + + @Nullable + @Override + public GuiEventListener getFocused() { + return element; + } + + @Override + public void setFocused(@Nullable GuiEventListener guiEventListener) { + if (guiEventListener == element) { + super.setFocused(element); + } else if (element instanceof ContainerEventHandler handler) { + handler.setFocused(guiEventListener); + } + } + + @Override + public boolean isDragging() { + return true; + } + + @Override + public boolean containsMouse(double mouseX, double mouseY) { + return element.isMouseOver(mouseX, mouseY); + } +} \ No newline at end of file diff --git a/runtime/src/main/resources/assets/roughlyenoughitems/lang/de_de.json b/runtime/src/main/resources/assets/roughlyenoughitems/lang/de_de.json index 9ef6b85dd..be57c125f 100644 --- a/runtime/src/main/resources/assets/roughlyenoughitems/lang/de_de.json +++ b/runtime/src/main/resources/assets/roughlyenoughitems/lang/de_de.json @@ -9,10 +9,27 @@ "text.rei.search.field.suggestion": "Suche...", "text.rei.feedback": "Möchtest du dem REI Entwickler dein Feedback geben? %s um dein Feedback einzureichen!", "text.rei.feedback.link": "Klicke hier um das Google-Form zu besuchen", + "text.rei.support.me": "Unterstütze mich, um REI weiter zu verbessern!", + "text.rei.support.me.desc": "Als Patreon Unterstützer von REI kannst du die neueste Version von REI für Minecraft Snapshots verwenden.\nAlternativ kannst du mich auch finanziell unterstützen, indem du einen BisectHosting Server mietst.\n\n%s\n%s", + "text.rei.support.me.patreon": "Spenden auf Patreon", + "text.rei.support.me.bisect": "Code SHEDANIEL auf BisectHosting verwenden", "text.rei.not.fully.initialized": "REI noch nicht vollständig initialisiert!", "text.rei.not.fully.initialized.tooltip": "Fehlende Stufen: %s\nFalls dies nicht weggeht,\nversuche mit den Logs nach Unterstützung zu suchen!", "text.rei.inventory.highlighting.enabled": "Inventarhervorhebung an", "text.rei.inventory.highlighting.enabled.tooltip": "Dies macht Slots, die nicht mit dem\nSuchfilter übereinstimmen grau.\nDoppelklicke die Suchleiste, um diesen Modus an- und auszuschalten.", + "text.rei.caching.search": "REI Caching Suchergebnisse...", + "text.rei.caching.search.step": "Schritt %d/%d (%s%%):", + "text.rei.config.menu.dark_theme": "Dunkles Design", + "text.rei.config.menu.craftable_filter": "Filter für Herstellbare Gegenstände", + "text.rei.config.menu.display": "Anzeigeeinstellungen", + "text.rei.config.menu.display.remove_recipe_book": "Rezeptbuch entfernen", + "text.rei.config.menu.display.left_side_mob_effects": "Linke Seite Mob-Effekte", + "text.rei.config.menu.display.left_side_panel": "Linke Seitenleiste", + "text.rei.config.menu.display.scrolling_side_panel": "Durchscrollbarer Seitenbereich", + "text.rei.config.menu.display.caching_entry_rendering": "Schnelleres Eintrags-Rendering", + "text.rei.config.menu.display.side_search_field": "Suchfeld", + "text.rei.config.menu.display.syntax_highlighting": "Syntax-Hervorhebung", + "text.rei.config.menu.config": "Weitere Optionen...", "category.rei.crafting": "Herstellen", "category.rei.smelting": "Schmelzen", "category.rei.smelting.fuel": "Brennstoff", @@ -39,6 +56,10 @@ "category.rei.beacon_payment": "Leuchtfeuerkosten", "category.rei.tilling": "Aufteilung", "category.rei.pathing": "Pfad", + "category.rei.waxing": "Wachsen", + "category.rei.wax_scraping": "Wachs abscharben", + "category.rei.oxidizing": "Oxidation", + "category.rei.oxidation_scraping": "Oxidationsabakratzung", "category.rei.information": "Information", "text.rei.composting.chance": "§e%d%% Chance", "text.rei.composting.page": "Seite %d", @@ -47,6 +68,7 @@ "text.rei.cheat_items": "[{item_name}] x{item_count} {player_name} gegeben.", "text.rei.failed_cheat_items": "§cItems geben fehlgeschlagen.", "text.rei.too_long_nbt": "§cGegenstand NBT ist zu lang, um im Multiplayer angewendet zu werden.", + "text.rei.tag_match": "Akzeptierter Tag: #%s", "text.rei.performance": "Leistungsanalyse", "ordering.rei.ascending": "Aufsteigend", "ordering.rei.descending": "Absteigend", @@ -54,12 +76,14 @@ "ordering.rei.name": "Name", "ordering.rei.item_groups": "Itemgruppen", "text.auto_craft.move_items": "Items bewegen", + "text.auto_craft.move_items.tooltip": "Strg-Klick zum Verschieben von Elementen", "text.auto_craft.move_items.yog": "Generiert NullPointerException!!", "error.rei.transfer.too_small": "Gegenstände können nicht in ein %dx%d-Raster verschoben werden.", "error.rei.not.on.server": "REI ist nicht auf dem Server installiert.", "error.rei.not.enough.materials": "Nicht genügend Materialien.", "error.rei.internal.error": "Interner Fehler: %s", "error.rei.recipe.not.unlocked": "Rezept nicht im Rezeptbuch freigeschaltet.", + "error.rei.not.supported.move.items": "Verschieben von Elementen wird mit diesem Rezept und diesem Container nicht unterstützt.", "error.rei.no.handlers.applicable": "Keine Handler anwendbar.", "error.rei.multi.errors": "Mehrere Fehler:", "rei.rei.no.slot.in.inv": "Kann keinen Platz für Gegenstand im Inventar finden", @@ -77,7 +101,14 @@ "text.rei.gamemode_button.tooltip.entry": "zu %s wechseln", "text.rei.weather_button.tooltip.dropdown": "Wetter ändern: Auswahl", "text.rei.weather_button.tooltip.entry": "zu %s wechseln", + "text.rei.time_button.tooltip.dropdown": "Wetter ändern: Auswahl", + "text.rei.time_button.tooltip.entry": "zu %s wechseln", + "text.rei.time_button.name.morn": "Morgen", + "text.rei.time_button.name.noon": "Mittag", + "text.rei.time_button.name.evening": "Abend", + "text.rei.time_button.name.night": "Nacht", "text.rei.reload_config": "Plugins neu laden", + "text.rei.reload_search": "Suche neu laden", "text.rei.config.is.reloading": "Plugins werden neu geladen!", "text.rei.enabled": "Ja", "text.rei.disabled": "Nein", @@ -112,8 +143,15 @@ "text.rei.tiny_potato": "Kleine Kartöffelchen", "text.rei.add_favorite_widget": "Hinzufügen...", "text.rei.dispose_here": "Hier verwerfen", + "text.rei.crash.title": "REI ist abgestürzt!", + "text.rei.crash.description": "§cRoughly Enough Items hat gerade einen Absturz während \"%s\" erlebt.\n\n§fDetails des Absturzes werden unten angezeigt. Bitte identifiziere die Modifikation, die den Absturz verursacht hat, und melde sie an den Mod-Autor, neben dem unten angegebenen Absturzprotokoll.\n\nWenn Sie glauben, dass dieser Absturz durch einen Fehler in Roughly Enough Items verursacht wird, melden Sie ihn bitte an unseren Issue-Tracker.\n\n§6Vielen Dank für deine Hilfe!\n", + "text.rei.crash.crash_report": "Absturzbericht öffnen", + "text.rei.changelog.title": "REI Änderungsliste", + "text.rei.changelog.error.missingChangelogFile": "Fehlende Änderungsprotokolldatei!", + "text.rei.changelog.error.failedToReadChangelogFile": "Fehler beim Lesen der Änderungsprotokolldatei!", "favorite.section.gamemode": "Spielmodus", "favorite.section.weather": "Wetter", + "favorite.section.time": "Zeit", "tooltip.rei.fluid_amount": "§7%d Einheit", "tooltip.rei.fluid_amount.forge": "§7%d mB", "tooltip.rei.drag_to_add_favorites": "§7Ziehe dies zu deinen Favoriten!", @@ -130,6 +168,7 @@ "config.roughlyenoughitems.functionality": "Funktionalität", "config.roughlyenoughitems.advanced": "Erweitert", "config.roughlyenoughitems.cheating": "Schummeln:", + "config.roughlyenoughitems.cheating.when_creative": "Im Kreativmodus", "config.roughlyenoughitems.favoritesEnabled": "Favoriten aktiviert:", "config.roughlyenoughitems.keyBindings": "Tastaturbelegungen", "config.roughlyenoughitems.keyBindings.recipeKeybind": "Zeige Rezept:", @@ -169,6 +208,10 @@ "config.roughlyenoughitems.layout.configButtonLocation.upper": "Obere", "config.roughlyenoughitems.layout.configButtonLocation.lower": "Untere", "config.roughlyenoughitems.layout.mergeDisplayUnderOne": "Vereine alle Displays mit demselben Inhalt", + "config.roughlyenoughitems.layout.favoriteAddWidgetMode": "Favoriten Widget-Schaltfläche hinzufügen:", + "config.roughlyenoughitems.layout.favoriteAddWidgetMode.always_invisible": "Immer unsichtbar", + "config.roughlyenoughitems.layout.favoriteAddWidgetMode.auto_hide": "Automatisch ausblenden", + "config.roughlyenoughitems.layout.favoriteAddWidgetMode.always_visible": "Immer sichtbar", "config.roughlyenoughitems.filteredEntries.selectAll": "Alles Auswählen", "config.roughlyenoughitems.filteredEntries.selectNone": "Alle abwählen", "config.roughlyenoughitems.filteredEntries.hide": "Auswahl verstecken", @@ -210,6 +253,9 @@ "config.roughlyenoughitems.disableRecipeBook": "Vanilla Rezeptbuch:", "config.roughlyenoughitems.disableRecipeBook.boolean.true": "§cNein", "config.roughlyenoughitems.disableRecipeBook.boolean.false": "§aJa", + "config.roughlyenoughitems.leftSideMobEffects": "Position der Mob-Effekte:", + "config.roughlyenoughitems.leftSideMobEffects.boolean.true": "Links", + "config.roughlyenoughitems.leftSideMobEffects.boolean.false": "Rechts (Vanilla)", "config.roughlyenoughitems.fixTabCloseContainer": "Korrigier den Vanilla Tab Container (wenn das Rezeptbuch deaktiviert ist):", "config.roughlyenoughitems.lighterButtonHover": "Helles Button-Hovern:", "config.roughlyenoughitems.layout.enableCraftableOnlyButton": "Filter für Herstellbare Gegenstände:", @@ -225,6 +271,8 @@ "config.roughlyenoughitems.layout.entryPanelOrdering": "Reihenfolge der Itemlisten:", "config.roughlyenoughitems.list_ordering_button": "%s [%s]", "config.roughlyenoughitems.miscellaneous.newFastEntryRendering": "Schnelleres Eintrags-Rendering:", + "config.roughlyenoughitems.miscellaneous.cachingFastEntryRendering": "Schnelleres Eintrags-Rendering:", + "config.roughlyenoughitems.miscellaneous.cachingFastEntryRendering.@PrefixText": "Diese Option verbessert die Leistung bei der Darstellung von Einträgen bis zu 5x, mit durchschnittlich 2. x Leistungssteigerung. Dies wird jedoch die Verzauberungsbrille und animierte Texturen zerstören/verbuggen.", "config.roughlyenoughitems.itemCheatingMode": "Anzahl der Gegenstände beim Cheaten:", "config.roughlyenoughitems.itemCheatingMode.rei_like": "Normal", "config.roughlyenoughitems.itemCheatingMode.jei_like": "Umgekehrt", @@ -248,6 +296,8 @@ "config.roughlyenoughitems.syntaxHighlightingMode.plain_underscored": "Normal unterstrichen", "config.roughlyenoughitems.syntaxHighlightingMode.colorful": "Farbig", "config.roughlyenoughitems.syntaxHighlightingMode.colorful_underscored": "Farbig unterstrichen", + "config.roughlyenoughitems.isFocusModeZoomed": "Autofokus-Modus", + "config.roughlyenoughitems.isFocusModeZoomed.boolean.true": "Gezoomt", "config.roughlyenoughitems.filteringScreen": "Benutzerdefinierte Filter", "config.roughlyenoughitems.filteringRulesScreen": "Benutzerdefinierte Filterregeln", "config.roughlyenoughitems.filteringRulesScreen.new": "Filterregel erstellen", diff --git a/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json b/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json index 6f8b677f0..2817ab195 100755 --- a/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json +++ b/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json @@ -70,13 +70,14 @@ "text.rei.too_long_nbt": "§cItem NBT is too long to be applied in multiplayer.", "text.rei.tag_match": "Accepts Tag: #%s", "text.rei.performance": "Performance Analysis", + "text.rei.shapeless": "Shapeless", "ordering.rei.ascending": "Ascending", "ordering.rei.descending": "Descending", "ordering.rei.registry": "Registry", "ordering.rei.name": "Name", "ordering.rei.item_groups": "Item Groups", "text.auto_craft.move_items": "Move Items", - "text.auto_craft.move_items.tooltip": "Ctrl-Click to Move Items", + "text.auto_craft.move_items.tooltip": "Ctrl-Click to Quick Craft", "text.auto_craft.move_items.yog": "Generate NullPointerException!!", "error.rei.transfer.too_small": "Unable to move items to a %dx%d grid.", "error.rei.not.on.server": "REI is not on the server.", diff --git a/runtime/src/main/resources/assets/roughlyenoughitems/lang/pt_br.json b/runtime/src/main/resources/assets/roughlyenoughitems/lang/pt_br.json index 0025052fb..35c9550e8 100644 --- a/runtime/src/main/resources/assets/roughlyenoughitems/lang/pt_br.json +++ b/runtime/src/main/resources/assets/roughlyenoughitems/lang/pt_br.json @@ -7,13 +7,17 @@ "text.rei.cheating_limited_creative_enabled": "§aAtivar trapaças (modo Criativo)", "text.rei.no_permission_cheat": "Você precisa ser um operador para obter itens", "text.rei.search.field.suggestion": "Buscar...", - "text.rei.feedback": "Deseja enviar feedback ao desenvolvedor do REI? %s para enviá-lo!", + "text.rei.feedback": "Deseja enviar um feedback ao desenvolvedor do REI? %s para enviá-lo!", "text.rei.feedback.link": "Acesse o formulário de feedback", + "text.rei.support.me": "Apoie o REI para torná-lo ainda melhor!", + "text.rei.support.me.desc": "Como apoiador do REI no Patreon, você pode baixar a versão mais recente do REI para snapshots.\nVocê também pode me apoiar ao alugar um servidor na BisectHosting.", + "text.rei.support.me.patreon": "Apoie o REI no Patreon", + "text.rei.support.me.bisect": "Use o código SHEDANIEL na BisectHosting", "text.rei.not.fully.initialized": "O REI ainda não está completamente inicializado!", "text.rei.not.fully.initialized.tooltip": "Etapas restantes: %s\nSe isso continuar,\nverifique os registros!\n", "text.rei.inventory.highlighting.enabled": "Destaque de inventário ativado", "text.rei.inventory.highlighting.enabled.tooltip": "Os espaços não encontrados na busca\nficarão da cor cinza.\nClique duas vezes na barra de busca para ativar o modo.", - "text.rei.caching.search": "Memorizando busca...", + "text.rei.caching.search": "Memorizando busca do REI...", "text.rei.caching.search.step": "Passo %d/%d (%s%%):", "text.rei.config.menu.dark_theme": "Tema escuro", "text.rei.config.menu.craftable_filter": "Fabricáveis", @@ -59,8 +63,8 @@ "category.rei.information": "Informações", "text.rei.composting.chance": "§e%d%% de chances", "text.rei.composting.page": "Pág. %d", - "text.rei.config": "Definições", - "text.rei.config_tooltip": "Abrir menu de definições\n§7Shift + clique para alternar o modo trapaça", + "text.rei.config": "Ajustes", + "text.rei.config_tooltip": "Abrir menu de ajustes\n§7Shift + clique para alternar o modo trapaça", "text.rei.cheat_items": "{player_name} recebeu {item_count} unidade(s) de [{item_name}§f].", "text.rei.failed_cheat_items": "§cFalha ao obter itens.", "text.rei.too_long_nbt": "§cO NBT do item é longo demais para ser aplicado ao modo multijogador.", @@ -75,10 +79,10 @@ "text.auto_craft.move_items.tooltip": "Ctrl + clique para mover itens", "text.auto_craft.move_items.yog": "Gerar NullPointerException!", "error.rei.transfer.too_small": "Não é possível mover os itens para uma grade %dx%d.", - "error.rei.not.on.server": "O REI não está disponível no servidor.", + "error.rei.not.on.server": "O REI não está no servidor.", "error.rei.not.enough.materials": "Matéria-prima insuficiente.", "error.rei.internal.error": "Erro interno: %s", - "error.rei.recipe.not.unlocked": "Receita inacessível no livro de receitas.", + "error.rei.recipe.not.unlocked": "Receita inacessível no livro.", "error.rei.not.supported.move.items": "Não é possível mover itens com essa receita e contêiner.", "error.rei.no.handlers.applicable": "Processo indisponível.", "error.rei.multi.errors": "Vários erros:", @@ -97,13 +101,14 @@ "text.rei.gamemode_button.tooltip.entry": "Mudar para %s", "text.rei.weather_button.tooltip.dropdown": "Alterar tempo: Lista", "text.rei.weather_button.tooltip.entry": "Mudar para %s", + "text.rei.time_button.tooltip.entry": "Alterar para %s", "text.rei.time_button.name.morn": "Manhã", "text.rei.time_button.name.noon": "Meio-dia", "text.rei.time_button.name.evening": "Fim de tarde", "text.rei.time_button.name.night": "Noite", - "text.rei.reload_config": "Recarregar plug-ins", + "text.rei.reload_config": "Recarregar plugins", "text.rei.reload_search": "Recarregar busca", - "text.rei.config.is.reloading": "Recarregando plug-ins!", + "text.rei.config.is.reloading": "Recarregando plugins!", "text.rei.enabled": "Sim", "text.rei.disabled": "Não", "text.rei.short_gamemode.survival": "S", @@ -126,11 +131,11 @@ "text.rei.release_export": "Solte %s para exportar", "text.rei.recipe_id": "\n%sID: %s", "text.rei.recipe_screen_type.selection": "Selecionar estilo da tela de receita", - "text.rei.recipe_screen_type.selection.sub": "Você sempre pode editar essa opção no menu de definições.", + "text.rei.recipe_screen_type.selection.sub": "Você sempre pode editar essa opção no menu de ajustes.", "text.rei.jei_compat": "Camada de compatibilidade do JEI", "text.rei.jei_compat.false": "Camada de compatibilidade do JEI: Não", "text.rei.jei_compat.true": "Camada de compatibilidade do JEI: Sim", - "text.rei.jei_compat.sub": "Deseja ativar a camada de compatibilidade do JEI %s§7?\n§7Você pode carregar plug-ins do JEI pelas seguintes fontes:\n%s\n\n§7Lembre-se de que a compatibilidade do REI com o JEI não é perfeita.\n§cUSE POR SUA CONTA E RISCO!", + "text.rei.jei_compat.sub": "Deseja ativar a camada de compatibilidade do JEI %s§7?\n§7Você pode carregar plugins do JEI pelas seguintes fontes:\n%s\n\n§7Lembre-se de que a compatibilidade do REI com o JEI não é perfeita.\n§cUSE POR SUA CONTA E RISCO!", "text.rei.jei_compat.sub.stability": "§c§l(ALFA)", "text.rei.view_recipes_for": "Ver receitas para %s", "text.rei.subsets": "Subconjuntos", @@ -138,10 +143,11 @@ "text.rei.add_favorite_widget": "Adicionar...", "text.rei.dispose_here": "Deixe aqui", "text.rei.crash.title": "O REI parou de funcionar!", + "text.rei.crash.description": "§cO Roughly Enough Items parou de funcionar durante o evento \"%s\".\n\n§fVeja os detalhes abaixo. Identifique o mod que causou a parada e informe ao autor com o relatório de erro abaixo.\n\nSe você acha que a parada foi causada por um erro no Roughly Enough Items, informe-o no issue tracker.\n\n§6Obrigado!", "text.rei.crash.crash_report": "Abrir relatório de erro", - "text.rei.changelog.title": "Registro de alterações", + "text.rei.changelog.title": "Log de alterações do REI", "text.rei.changelog.error.missingChangelogFile": "Registro ausente!", - "text.rei.changelog.error.failedToReadChangelogFile": "Falha ao ler registro!", + "text.rei.changelog.error.failedToReadChangelogFile": "Falha ao ler o log!", "favorite.section.gamemode": "Modo de jogo", "favorite.section.weather": "Tempo", "tooltip.rei.fluid_amount": "§7%d unidade(s)", @@ -153,8 +159,8 @@ "msg.rei.exported_recipe.desc": "Verifique a pasta \"rei_exports\".", "subsets.rei.roughlyenoughitems.all_entries": "Todas", "subsets.rei.roughlyenoughitems.item_groups": "Guias do Criativo", - "_comment": "Descrições de definições", - "config.roughlyenoughitems.title": "Definições do Roughly Enough Items", + "_comment": "Descrição de ajustes", + "config.roughlyenoughitems.title": "Ajustes do Roughly Enough Items", "config.roughlyenoughitems.basics": "Básico", "config.roughlyenoughitems.appearance": "Estilo", "config.roughlyenoughitems.functionality": "Funções", @@ -176,8 +182,8 @@ "config.roughlyenoughitems.cheatingStyle": "Estilo de trapaça:", "config.roughlyenoughitems.cheatingStyle.grab": "Pegar", "config.roughlyenoughitems.cheatingStyle.give": "Dar", - "config.roughlyenoughitems.motion": "Definições de animações", - "config.roughlyenoughitems.motion.configScreenAnimation": "Animação da tela de def.:", + "config.roughlyenoughitems.motion": "Ajustes de animação", + "config.roughlyenoughitems.motion.configScreenAnimation": "Animação dos ajustes:", "config.roughlyenoughitems.motion.creditsScreenAnimation": "Animação da tela de créditos:", "config.roughlyenoughitems.motion.favoritesAnimation": "Favoritos animados:", "config.roughlyenoughitems.recipeScreenType": "Estilo da tela de receita:", @@ -196,10 +202,11 @@ "config.roughlyenoughitems.isSubsetsEnabled": "Ativar subconjuntos:", "config.roughlyenoughitems.allowInventoryHighlighting": "Destaque de inventário ativado:", "config.roughlyenoughitems.miscellaneous.renderEntryEnchantmentGlint": "Brilho do encantamento:", - "config.roughlyenoughitems.layout.configButtonLocation": "Posição dos botões de definições:", + "config.roughlyenoughitems.layout.configButtonLocation": "Posição dos botões de ajustes:", "config.roughlyenoughitems.layout.configButtonLocation.upper": "Superior", "config.roughlyenoughitems.layout.configButtonLocation.lower": "Inferior", "config.roughlyenoughitems.layout.mergeDisplayUnderOne": "Unir visores de conteúdo idêntico:", + "config.roughlyenoughitems.layout.favoriteAddWidgetMode": "Botão de widget dos favoritos:", "config.roughlyenoughitems.layout.favoriteAddWidgetMode.always_invisible": "Sempre invisível", "config.roughlyenoughitems.layout.favoriteAddWidgetMode.auto_hide": "Ocultar auto.", "config.roughlyenoughitems.layout.favoriteAddWidgetMode.always_visible": "Sempre visível", @@ -219,7 +226,7 @@ "config.roughlyenoughitems.recipeBorder.lighter": "Claro", "config.roughlyenoughitems.recipeBorder.default": "Padrão", "config.roughlyenoughitems.recipeBorder.none": "Não", - "config.roughlyenoughitems.layout.maxRecipesPerPage": "Máximo de receitas por página:", + "config.roughlyenoughitems.layout.maxRecipesPerPage": "Limite de receitas por página:", "config.roughlyenoughitems.layout.maxRecipesPageHeight": "Altura máxima da página de receitas:", "config.roughlyenoughitems.accessibility.displayPanelLocation": "Posição do painel de entradas:", "config.roughlyenoughitems.accessibility.displayPanelLocation.left": "Esquerdo", @@ -232,7 +239,7 @@ "config.roughlyenoughitems.search_mode.prefix": "Ao usar prefixo", "config.roughlyenoughitems.search_mode.never": "Sempre inativo", "config.roughlyenoughitems.layout.debugRenderTimeRequired": "Depuração do painel de entradas:", - "config.roughlyenoughitems.search.debugSearchTimeRequired": "Modo de busca por depuração:", + "config.roughlyenoughitems.search.debugSearchTimeRequired": "Busca por depuração:", "config.roughlyenoughitems.accessibility.resizeDynamically": "Escala dinâmica:", "config.roughlyenoughitems.layout.searchFieldLocation": "Posição do campo de busca:", "config.roughlyenoughitems.layout.searchFieldLocation.bottom_side": "Inferior esq./Direita", @@ -249,10 +256,10 @@ "config.roughlyenoughitems.leftSideMobEffects.boolean.false": "Direita (padrão)", "config.roughlyenoughitems.fixTabCloseContainer": "Corrigir contêiner de guias padrão (livro de receitas desativado):", "config.roughlyenoughitems.lighterButtonHover": "Cursor mínimo do botão:", - "config.roughlyenoughitems.layout.enableCraftableOnlyButton": "Filtro (fabricáveis):", + "config.roughlyenoughitems.layout.enableCraftableOnlyButton": "Filtro de fabricáveis:", "config.roughlyenoughitems.layout.showUtilsButtons": "Botões utilitários:", "config.roughlyenoughitems.commands.gamemodeCommand": "Comando do modo de jogo:", - "config.roughlyenoughitems.commands.giveCommand": "Comando give:", + "config.roughlyenoughitems.commands.giveCommand": "Comando \"give\":", "config.roughlyenoughitems.miscellaneous.loadDefaultPlugin": "Carregar plug-in padrão:", "config.roughlyenoughitems.miscellaneous.loadDefaultPlugin.boolean.false": "§cNão (perigoso)", "config.roughlyenoughitems.miscellaneous.registerRecipesInAnotherThread": "Thread de recarga:", @@ -263,14 +270,15 @@ "config.roughlyenoughitems.list_ordering_button": "%s [%s]", "config.roughlyenoughitems.miscellaneous.newFastEntryRendering": "Renderização rápida de entradas:", "config.roughlyenoughitems.miscellaneous.cachingFastEntryRendering": "Memorizando entrada:", - "config.roughlyenoughitems.itemCheatingMode": "Quantidade de itens por trapaça:", + "config.roughlyenoughitems.miscellaneous.cachingFastEntryRendering.@PrefixText": "Essa opção aumentará o desempenho em até cinco vezes ao renderizar as entradas, com uma média de duas vezes e meia de ganho. As texturas animadas e brilhos cintilantes serão desativados.", + "config.roughlyenoughitems.itemCheatingMode": "Número de itens por trapaça:", "config.roughlyenoughitems.itemCheatingMode.rei_like": "Comum", "config.roughlyenoughitems.itemCheatingMode.jei_like": "Invertido", "config.roughlyenoughitems.search.searchFavorites": "Filtro de busca nos favoritos:", "config.roughlyenoughitems.tooltips.appendModNames": "Incluir nomes de mods:", "config.roughlyenoughitems.tooltips.displayFavoritesTooltip": "Incluir dicas aos favoritos:", "config.roughlyenoughitems.accessibility.snapToRows": "Linhas de troca de entradas:", - "config.roughlyenoughitems.accessibility.toastDisplayedOnCopyIdentifier": "Copiar toast:", + "config.roughlyenoughitems.accessibility.toastDisplayedOnCopyIdentifier": "Copiar toast de identificação:", "config.roughlyenoughitems.scrollingEntryListWidget": "Formato da lista de entradas:", "config.roughlyenoughitems.scrollingEntryListWidget.boolean.true": "Rolagem", "config.roughlyenoughitems.scrollingEntryListWidget.boolean.false": "Páginas", @@ -289,6 +297,7 @@ "config.roughlyenoughitems.isFocusModeZoomed": "Modo de foco da entrada:", "config.roughlyenoughitems.isFocusModeZoomed.boolean.true": "Ampliado", "config.roughlyenoughitems.isFocusModeZoomed.boolean.false": "Realçado", + "config.roughlyenoughitems.filtering.shouldFilterDisplays": "Exibir filtros:", "config.roughlyenoughitems.filteringScreen": "Filtro personalizado", "config.roughlyenoughitems.filteringRulesScreen": "Regras de filtros personalizados", "config.roughlyenoughitems.filteringRulesScreen.new": "Criar regra para filtro", @@ -296,7 +305,7 @@ "rule.roughlyenoughitems.filtering.manual": "Filtro manual", "rule.roughlyenoughitems.filtering.manual.subtitle": "Selecionar manualmente o que ocultar e mostrar.", "rule.roughlyenoughitems.filtering.search": "Filtro de busca", - "rule.roughlyenoughitems.filtering.search.subtitle": "Utilize os filtros para delimitar a busca.", + "rule.roughlyenoughitems.filtering.search.subtitle": "Use os filtros para delimitar a busca.", "rule.roughlyenoughitems.filtering.search.filter": "Filtro de busca:", "rule.roughlyenoughitems.filtering.search.show": "Mostrar/Ocultar:", "rule.roughlyenoughitems.filtering.search.show.true": "Mostrar", diff --git a/runtime/src/main/resources/assets/roughlyenoughitems/lang/zh_cn.json b/runtime/src/main/resources/assets/roughlyenoughitems/lang/zh_cn.json index aec8aad67..030d2827c 100644 --- a/runtime/src/main/resources/assets/roughlyenoughitems/lang/zh_cn.json +++ b/runtime/src/main/resources/assets/roughlyenoughitems/lang/zh_cn.json @@ -70,13 +70,14 @@ "text.rei.too_long_nbt": "§c物品 NBT 太长,不能应用于多人游戏.", "text.rei.tag_match": "接受标签: #%s", "text.rei.performance": "性能分析", + "text.rei.shapeless": "无序合成", "ordering.rei.ascending": "顺序", "ordering.rei.descending": "倒序", "ordering.rei.registry": "物品ID循序", "ordering.rei.name": "名称循序", "ordering.rei.item_groups": "物品分类的循序", "text.auto_craft.move_items": "移动物品", - "text.auto_craft.move_items.tooltip": "Ctrl+单击 以移动物品", + "text.auto_craft.move_items.tooltip": "Ctrl+单击 以快速合成", "text.auto_craft.move_items.yog": "Generate NullPointerException!!", "error.rei.transfer.too_small": "无法将移动物品到 %dx%d 的方格上.", "error.rei.not.on.server": "服务器没有安装 REI", @@ -221,6 +222,7 @@ "config.roughlyenoughitems.search.asyncSearch": "异步搜索:", "config.roughlyenoughitems.search.asyncSearchPartitionSize": "异步搜索划分大小:", "config.roughlyenoughitems.accessibility.useCompactTabs": "简洁标签:", + "config.roughlyenoughitems.accessibility.useCompactTabButtons": "简洁标签分页按钮:", "config.roughlyenoughitems.theme": "外观主题:", "config.roughlyenoughitems.theme.dark": "深色主题", "config.roughlyenoughitems.theme.light": "浅色主题", diff --git a/runtime/src/main/resources/assets/roughlyenoughitems/lang/zh_tw.json b/runtime/src/main/resources/assets/roughlyenoughitems/lang/zh_tw.json index d035ae78a..c84594ebf 100644 --- a/runtime/src/main/resources/assets/roughlyenoughitems/lang/zh_tw.json +++ b/runtime/src/main/resources/assets/roughlyenoughitems/lang/zh_tw.json @@ -70,13 +70,14 @@ "text.rei.too_long_nbt": "§c物品 NBT 過長,不適用於多人遊戲。", "text.rei.tag_match": "接受標籤: #%s", "text.rei.performance": "效能分析", + "text.rei.shapeless": "無序合成", "ordering.rei.ascending": "從 A 到 Z", "ordering.rei.descending": "從 Z 到 A", "ordering.rei.registry": "註冊名", "ordering.rei.name": "名稱", "ordering.rei.item_groups": "物品分類", "text.auto_craft.move_items": "移動物品", - "text.auto_craft.move_items.tooltip": "按住《Ctrl》鍵再點擊此處以移動物品", + "text.auto_craft.move_items.tooltip": "