From 598dfc5c1f5e532a34f09c7d8d398ec727a33ab3 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Thu, 26 Oct 2023 15:49:00 +0800 Subject: Localise more values and add a basic theme previewer --- .../config/components/ConfigEntriesListWidget.java | 1 + .../gui/config/components/ConfigGroupWidget.java | 57 +++++++++++++++------ .../config/components/ConfigOptionValueWidget.java | 6 ++- .../gui/config/components/ConfigOptionWidget.java | 58 ++++++++++++++++++---- .../gui/config/options/AllREIConfigGroups.java | 3 +- .../gui/config/options/AllREIConfigOptions.java | 24 +++++++-- .../client/gui/config/options/CompositeOption.java | 18 +++++++ .../gui/config/options/OptionValueEntry.java | 38 ++++++++++++-- .../gui/config/options/preview/ThemePreviewer.java | 17 ++++++- .../assets/roughlyenoughitems/lang/en_us.json | 39 ++++++++++++++- 10 files changed, 222 insertions(+), 39 deletions(-) (limited to 'runtime/src') diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigEntriesListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigEntriesListWidget.java index 6f580d3a3..de05300eb 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigEntriesListWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigEntriesListWidget.java @@ -38,6 +38,7 @@ public class ConfigEntriesListWidget { WidgetWithBounds list = ListWidget.builderOf(RectangleUtils.inset(bounds, 6, 6), groups, (index, entry) -> ConfigGroupWidget.create(entry, bounds.width - 12 - 6)) .gap(7) + .calculateTotalHeightDynamically(true) .build(); return ScrollableViewWidget.create(bounds, list.withPadding(0, 5), true); } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigGroupWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigGroupWidget.java index 76d41e4f1..fdad7818d 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigGroupWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigGroupWidget.java @@ -23,45 +23,70 @@ package me.shedaniel.rei.impl.client.gui.config.components; +import com.mojang.math.Matrix4f; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; 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; +import me.shedaniel.rei.api.client.util.MatrixUtils; import me.shedaniel.rei.impl.client.gui.config.options.CompositeOption; import me.shedaniel.rei.impl.client.gui.config.options.OptionGroup; import net.minecraft.client.gui.GuiComponent; +import org.apache.commons.lang3.tuple.Triple; +import java.util.AbstractList; import java.util.ArrayList; import java.util.List; +import java.util.function.Supplier; public class ConfigGroupWidget { public static WidgetWithBounds create(OptionGroup entry, int width) { - List widgets = new ArrayList<>(); - int height = 0; + List, Matrix4f[]>> widgets = new ArrayList<>(); + int[] height = {0}; WidgetWithBounds groupTitle = Widgets.createLabel(new Point(0, 3), entry.getGroupName().copy().withStyle(style -> style.withColor(0xFFC0C0C0).withUnderlined(true))) - .leftAligned(); - groupTitle = groupTitle.withPadding(0, 0, 0, 6); - widgets.add(groupTitle); - height = Math.max(height, groupTitle.getBounds().getMaxY()); + .leftAligned() + .withPadding(0, 0, 0, 6); + widgets.add(Triple.of(groupTitle, groupTitle::getBounds, new Matrix4f[]{new Matrix4f()})); + height[0] = Math.max(height[0], groupTitle.getBounds().getMaxY()); for (CompositeOption option : entry.getOptions()) { - WidgetWithBounds widget = ConfigOptionWidget.create(option, width); - widgets.add(Widgets.withTranslate(widget, 0, height, 0)); - height = Math.max(height, height + widget.getBounds().getMaxY()); + Matrix4f[] translation = new Matrix4f[]{Matrix4f.createTranslateMatrix(0, height[0], 0)}; + WidgetWithBounds widget = Widgets.withTranslate(ConfigOptionWidget.create(option, width), () -> translation[0]); + widgets.add(Triple.of(widget, () -> MatrixUtils.transform(translation[0], widget.getBounds()), translation)); + height[0] = Math.max(height[0], widget.getBounds().getMaxY()); if (entry.getOptions().get(entry.getOptions().size() - 1) != option) { - int y = height; - widgets.add(Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> { + Matrix4f[] translationDrawable = new Matrix4f[]{Matrix4f.createTranslateMatrix(0, height[0], 0)}; + widgets.add(Triple.of(Widgets.withTranslate(Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> { for (int x = 0; x <= width; x += 4) { - GuiComponent.fill(matrices, x, y + 1, x + 2, y + 2, 0xFF757575); + GuiComponent.fill(matrices, x, 1, x + 2, 2, 0xFF757575); } - })); - height += 7; + }), () -> translationDrawable[0]), () -> + MatrixUtils.transform(translationDrawable[0], new Rectangle(0, 0, 1, 7)), translationDrawable)); + height[0] += 7; } } - Rectangle bounds = new Rectangle(0, 0, width, height); - return Widgets.concatWithBounds(bounds, widgets); + widgets.add(Triple.of(Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> { + int h = 0; + for (Triple, Matrix4f[]> widget : widgets) { + widget.getRight()[0] = Matrix4f.createTranslateMatrix(0, h, 0); + h = Math.max(h, widget.getMiddle().get().getMaxY()); + } + height[0] = h; + }), Rectangle::new, new Matrix4f[]{new Matrix4f()})); + + return Widgets.concatWithBounds(() -> new Rectangle(0, 0, width, height[0]), new AbstractList<>() { + @Override + public Widget get(int index) { + return widgets.get(index).getLeft(); + } + + @Override + public int size() { + return widgets.size(); + } + }); } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigOptionValueWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigOptionValueWidget.java index f2764dd2d..e2d62eed3 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigOptionValueWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigOptionValueWidget.java @@ -23,6 +23,7 @@ package me.shedaniel.rei.impl.client.gui.config.components; +import com.google.common.base.MoreObjects; import com.mojang.math.Matrix4f; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; @@ -43,6 +44,7 @@ import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import java.util.Map; +import java.util.Objects; import static me.shedaniel.rei.impl.client.gui.config.options.ConfigUtils.literal; import static me.shedaniel.rei.impl.client.gui.config.options.ConfigUtils.translatable; @@ -61,7 +63,7 @@ public class ConfigOptionValueWidget { text[0] = literal(value.toString()); } - if (value.equals(defaultOptions.get(option))) { + if (value.equals(Objects.requireNonNullElseGet(option.getDefaultValue(), () -> (T) defaultOptions.get(option)))) { text[0] = translatable("config.rei.value.default", text[0]); } @@ -84,7 +86,7 @@ public class ConfigOptionValueWidget { ((Map, Object>) options).put(option, selection.getOptions().get((selection.getOptions().indexOf((T) options.get(option)) + 1) % 2)); text[0] = selection.getOption((T) options.get(option)); - if (options.get(option).equals(defaultOptions.get(option))) { + if (options.get(option).equals(Objects.requireNonNullElseGet(option.getDefaultValue(), () -> (T) defaultOptions.get(option)))) { text[0] = translatable("config.rei.value.default", text[0]); } }); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigOptionWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigOptionWidget.java index 9707b3ab7..2c157767e 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigOptionWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigOptionWidget.java @@ -25,17 +25,25 @@ package me.shedaniel.rei.impl.client.gui.config.components; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Matrix4f; +import me.shedaniel.clothconfig2.api.ScissorsHandler; +import me.shedaniel.clothconfig2.api.animator.NumberAnimator; +import me.shedaniel.clothconfig2.api.animator.ValueAnimator; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.gui.widgets.Label; 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; +import me.shedaniel.rei.api.client.util.MatrixUtils; +import me.shedaniel.rei.impl.client.gui.config.REIConfigScreen; import me.shedaniel.rei.impl.client.gui.config.options.CompositeOption; +import me.shedaniel.rei.impl.common.util.RectangleUtils; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiComponent; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.network.chat.MutableComponent; import net.minecraft.util.FormattedCharSequence; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; @@ -43,8 +51,9 @@ import java.util.List; import static me.shedaniel.rei.impl.client.gui.config.options.ConfigUtils.translatable; public class ConfigOptionWidget { - public static WidgetWithBounds create(CompositeOption option, int width) { + public static WidgetWithBounds create(CompositeOption option, int width) { List widgets = new ArrayList<>(); + int[] stableHeight = {12}; int[] height = {12}; widgets.add(Widgets.createLabel(new Point(0, 0), option.getName().copy().withStyle(style -> style.withColor(0xFFC0C0C0))) .leftAligned()); @@ -54,21 +63,28 @@ public class ConfigOptionWidget { final MutableComponent description = option.getDescription().copy().withStyle(style -> style.withColor(0xFF757575)); final List split = Minecraft.getInstance().font.split(description, width); final boolean hasPreview = option.hasPreview(); - final Label preview = Widgets.createLabel(new Point(), translatable("config.rei.texts.preview")) + final Label previewLabel = Widgets.createLabel(new Point(), translatable("config.rei.texts.preview")) .color(0xFFA5F4FF) .hoveredColor(0xFFD1FAFF) .noShadow() .clickable() + .onClick($ -> clickPreview()) .rightAligned(); + @Nullable + WidgetWithBounds preview = null; + boolean previewVisible = false; + Matrix4f previewTranslation = new Matrix4f(); + final NumberAnimator previewHeight = ValueAnimator.ofFloat() + .withConvention(() -> previewVisible ? preview.getBounds().getHeight() : 0f, ValueAnimator.typicalTransitionTime()); boolean nextLinePreview = false; { - height[0] += 12 * split.size(); + stableHeight[0] += 12 * split.size(); if (hasPreview) { int lastWidth = Minecraft.getInstance().font.width(split.get(split.size() - 1)); - if (lastWidth + preview.getBounds().width + 10 > width) { + if (lastWidth + this.previewLabel.getBounds().width + 10 > width) { nextLinePreview = true; - height[0] += 12; + stableHeight[0] += 12; } } } @@ -80,26 +96,48 @@ public class ConfigOptionWidget { @Override public void render(PoseStack poses, int mouseX, int mouseY, float delta) { + this.previewHeight.update(delta); + height[0] = stableHeight[0] + Math.round(this.previewHeight.value()); + for (int i = 0; i < split.size(); i++) { Minecraft.getInstance().font.draw(poses, split.get(i), 0, 12 + 12 * i, -1); } if (hasPreview) { if (nextLinePreview) { - this.preview.setPoint(new Point(width, 12 + 12 * split.size())); + this.previewLabel.setPoint(new Point(width, 12 + 12 * split.size())); } else { - this.preview.setPoint(new Point(width, 12 + 12 * split.size() - 12)); + this.previewLabel.setPoint(new Point(width, 12 + 12 * split.size() - 12)); } - this.preview.render(poses, mouseX, mouseY, delta); + this.previewLabel.render(poses, mouseX, mouseY, delta); + + if (this.preview != null && this.previewHeight.value() > 0.1f) { + ScissorsHandler.INSTANCE.scissor(MatrixUtils.transform(poses.last().pose(), new Rectangle(0, 24 + 12 * split.size() - (nextLinePreview ? 0 : 12), width, this.previewHeight.value()))); + this.previewTranslation = Matrix4f.createTranslateMatrix(0, 12 + 12 * split.size(), 100); + this.preview.render(poses, mouseX, mouseY, delta); + ScissorsHandler.INSTANCE.removeLastScissor(); + } } } + private void clickPreview() { + if (this.preview == null) { + this.preview = option.getPreviewer().preview(width, () -> (T) ((REIConfigScreen) Minecraft.getInstance().screen).getOptions().get(option)); + this.preview = Widgets.withTranslate(this.preview, () -> this.previewTranslation); + } + + this.previewVisible = !this.previewVisible; + } + @Override public List children() { - return List.of(preview); + if (this.preview != null && this.previewHeight.value() > 0.1f) return List.of(this.previewLabel, this.preview); + return List.of(this.previewLabel); } }); - return Widgets.concatWithBounds(new Rectangle(0, 0, width, height[0]), widgets); + + height[0] = stableHeight[0]; + return Widgets.concatWithBounds(() -> new Rectangle(0, 0, width, height[0]), widgets); } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigGroups.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigGroups.java index 60a78a657..87725f710 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigGroups.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigGroups.java @@ -53,7 +53,8 @@ interface AllREIConfigGroups { .add(CONFIG_BUTTON_LOCATION) .add(CRAFTABLE_FILTER); OptionGroup LAYOUT_PANEL = make("layout.panel") - .add(BOUNDARIES); + .add(BOUNDARIES) + .add(LOCATION); OptionGroup ACCESSIBILITY_DISPLAY = make("accessibility.display") .add(LARGER_TABS) .add(LARGER_ARROW_BUTTONS); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java index 58827c465..f418e9edd 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java @@ -25,11 +25,14 @@ package me.shedaniel.rei.impl.client.gui.config.options; import me.shedaniel.rei.api.client.gui.config.*; import me.shedaniel.rei.impl.client.config.ConfigObjectImpl; +import me.shedaniel.rei.impl.client.gui.config.REIConfigScreen; import me.shedaniel.rei.impl.client.gui.config.options.preview.ThemePreviewer; +import net.minecraft.client.Minecraft; import java.util.function.BiConsumer; import java.util.function.Function; +import static me.shedaniel.rei.impl.client.gui.config.options.ConfigUtils.literal; import static me.shedaniel.rei.impl.client.gui.config.options.ConfigUtils.translatable; interface AllREIConfigOptions { @@ -47,7 +50,8 @@ interface AllREIConfigOptions { CompositeOption REDUCED_MOTION = make("appearance.reduced_motion", i -> i.basics.reduceMotion, (i, v) -> i.basics.reduceMotion = v) .enabledDisabled(); CompositeOption RECIPE_LOOKUP_STYLE = make("appearance.recipe_lookup_style", i -> i.appearance.recipeScreenType, (i, v) -> i.appearance.recipeScreenType = v) - .enumOptions(); + .options(DisplayScreenType.ORIGINAL, DisplayScreenType.COMPOSITE) + .defaultValue(() -> DisplayScreenType.ORIGINAL); CompositeOption APPEND_MOD_NAMES = make("appearance.append_mod_names", i -> i.advanced.tooltips.appendModNames, (i, v) -> i.advanced.tooltips.appendModNames = v) .enabledDisabled(); CompositeOption APPEND_FAVORITES_HINT = make("appearance.append_favorites_hint", i -> i.advanced.tooltips.displayFavoritesTooltip, (i, v) -> i.advanced.tooltips.displayFavoritesTooltip = v) @@ -63,14 +67,28 @@ interface AllREIConfigOptions { .enumOptions(); CompositeOption GIVE_COMMAND = make("cheats.give_command", i -> i.advanced.commands.giveCommand, (i, v) -> i.advanced.commands.giveCommand = v); CompositeOption SEARCH_FIELD_LOCATION = make("layout.search_field_location", i -> i.appearance.layout.searchFieldLocation, (i, v) -> i.appearance.layout.searchFieldLocation = v) - .enumOptions(); + .entry(OptionValueEntry.enumOptions().overrideText(location -> { + if (Minecraft.getInstance().screen instanceof REIConfigScreen configScreen) { + return literal(location.toString(configScreen.getOptions().get(AllREIConfigOptions.LOCATION) == DisplayPanelLocation.RIGHT)); + } else { + return literal(location.toString(true)); + } + })); CompositeOption CONFIG_BUTTON_LOCATION = make("layout.config_button_location", i -> i.appearance.layout.configButtonLocation, (i, v) -> i.appearance.layout.configButtonLocation = v) - .enumOptions(); + .entry(OptionValueEntry.enumOptions().overrideText(location -> { + if (Minecraft.getInstance().screen instanceof REIConfigScreen configScreen) { + return literal(location.toString(configScreen.getOptions().get(AllREIConfigOptions.LOCATION) == DisplayPanelLocation.RIGHT)); + } else { + return literal(location.toString(true)); + } + })); CompositeOption CRAFTABLE_FILTER = make("layout.craftable_filter", i -> i.appearance.layout.showCraftableOnlyButton, (i, v) -> i.appearance.layout.showCraftableOnlyButton = v) .enabledDisabled(); // TODO: BOUNDARIES CompositeOption BOUNDARIES = make("layout.boundaries", i -> true, (i, v) -> { }); + CompositeOption LOCATION = make("layout.location", i -> i.advanced.accessibility.displayPanelLocation, (i, v) -> i.advanced.accessibility.displayPanelLocation = v) + .enumOptions(); CompositeOption LARGER_TABS = make("accessibility.larger_tabs", i -> !i.advanced.accessibility.useCompactTabs, (i, v) -> i.advanced.accessibility.useCompactTabs = !v) .enabledDisabled(); CompositeOption LARGER_ARROW_BUTTONS = make("accessibility.larger_arrow_buttons", i -> !i.advanced.accessibility.useCompactTabButtons, (i, v) -> i.advanced.accessibility.useCompactTabButtons = !v) diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/CompositeOption.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/CompositeOption.java index 11f9126db..b0eb11a08 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/CompositeOption.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/CompositeOption.java @@ -29,6 +29,7 @@ import org.jetbrains.annotations.Nullable; import java.util.function.BiConsumer; import java.util.function.Function; +import java.util.function.Supplier; public class CompositeOption { private final Component name; @@ -37,6 +38,8 @@ public class CompositeOption { private final BiConsumer save; @Nullable private ConfigPreviewer previewer; + @Nullable + private Supplier defaultValue = null; private OptionValueEntry entry; public CompositeOption(Component name, Component description, Function bind, BiConsumer save) { @@ -67,11 +70,20 @@ public class CompositeOption { return this.entry(OptionValueEntry.enumOptions(entry)); } + public CompositeOption options(T... entry) { + return this.entry(OptionValueEntry.options(entry)); + } + public CompositeOption previewer(ConfigPreviewer previewer) { this.previewer = previewer; return this; } + public CompositeOption defaultValue(Supplier defaultValue) { + this.defaultValue = defaultValue; + return this; + } + public Component getName() { return name; } @@ -100,4 +112,10 @@ public class CompositeOption { public boolean hasPreview() { return previewer != null; } + + @Nullable + public T getDefaultValue() { + if (defaultValue == null) return null; + return defaultValue.get(); + } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/OptionValueEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/OptionValueEntry.java index 6ec876266..303d16607 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/OptionValueEntry.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/OptionValueEntry.java @@ -26,7 +26,9 @@ package me.shedaniel.rei.impl.client.gui.config.options; import me.shedaniel.rei.api.common.util.CollectionUtils; import net.minecraft.network.chat.Component; +import java.util.Arrays; import java.util.List; +import java.util.function.Function; import static me.shedaniel.rei.impl.client.gui.config.options.ConfigUtils.literal; import static me.shedaniel.rei.impl.client.gui.config.options.ConfigUtils.translatable; @@ -37,7 +39,7 @@ public interface OptionValueEntry { }; } - static OptionValueEntry ofBoolean(Component falseText, Component trueText) { + static OptionValueEntry.Selection ofBoolean(Component falseText, Component trueText) { return new Selection() { @Override public List getOptions() { @@ -51,17 +53,17 @@ public interface OptionValueEntry { }; } - static OptionValueEntry trueFalse() { + static OptionValueEntry.Selection trueFalse() { return ofBoolean(translatable("config.rei.value.trueFalse.false"), translatable("config.rei.value.trueFalse.true")); } - static OptionValueEntry enabledDisabled() { + static OptionValueEntry.Selection enabledDisabled() { return ofBoolean(translatable("config.rei.value.enabledDisabled.false"), translatable("config.rei.value.enabledDisabled.true")); } - static OptionValueEntry enumOptions(T... array) { + static OptionValueEntry.Selection enumOptions(T... array) { Class type = (Class) array.getClass().getComponentType(); Object[] constants = type.getEnumConstants(); return new Selection() { @@ -77,9 +79,37 @@ public interface OptionValueEntry { }; } + static OptionValueEntry options(T... options) { + return new Selection() { + @Override + public List getOptions() { + return Arrays.asList(options); + } + + @Override + public Component getOption(T value) { + return literal(value.toString()); + } + }; + } + interface Selection extends OptionValueEntry { List getOptions(); Component getOption(T value); + + default Selection overrideText(Function textFunction) { + return new Selection() { + @Override + public List getOptions() { + return Selection.this.getOptions(); + } + + @Override + public Component getOption(T value) { + return textFunction.apply(value); + } + }; + } } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/preview/ThemePreviewer.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/preview/ThemePreviewer.java index df5ac9be6..42fcc9cee 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/preview/ThemePreviewer.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/preview/ThemePreviewer.java @@ -24,12 +24,16 @@ package me.shedaniel.rei.impl.client.gui.config.options.preview; import me.shedaniel.clothconfig2.api.animator.ValueAnimator; +import me.shedaniel.math.Color; +import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.gui.config.AppearanceTheme; +import me.shedaniel.rei.api.client.gui.widgets.Label; import me.shedaniel.rei.api.client.gui.widgets.Panel; import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds; import me.shedaniel.rei.api.client.gui.widgets.Widgets; import me.shedaniel.rei.impl.client.gui.config.options.ConfigPreviewer; +import me.shedaniel.rei.impl.client.gui.config.options.ConfigUtils; import me.shedaniel.rei.impl.client.gui.widget.basewidgets.PanelWidget; import java.util.List; @@ -40,10 +44,19 @@ public enum ThemePreviewer implements ConfigPreviewer { @Override public WidgetWithBounds preview(int width, Supplier value) { - Panel base = Widgets.createCategoryBase(new Rectangle(width * 10 / 2, 3, width * 10 / 8, 20)); + Panel base = Widgets.createCategoryBase(new Rectangle(width * 5 / 20, 3, width * 5 / 10, 50)); ((PanelWidget) base).setDarkBackgroundAlpha(ValueAnimator.ofFloat() .withConvention(() -> value.get() == AppearanceTheme.DARK ? 1.0F : 0.0F, ValueAnimator.typicalTransitionTime()) .asFloat()); - return Widgets.concatWithBounds(new Rectangle(0, 0, width, 26), List.of(base)); + ValueAnimator labelColor = ValueAnimator.ofColor(value.get() == AppearanceTheme.LIGHT ? Color.ofTransparent(0xFF404040) : Color.ofTransparent(0xFFBBBBBB)) + .withConvention(() -> value.get() == AppearanceTheme.LIGHT ? Color.ofTransparent(0xFF404040) : Color.ofTransparent(0xFFBBBBBB), ValueAnimator.typicalTransitionTime()); + Label label = Widgets.createLabel(new Point(width / 2, 24), ConfigUtils.literal("Preview")) + .centered() + .noShadow() + .color(labelColor.value().getColor()); + return Widgets.concatWithBounds(new Rectangle(0, 0, width, 56), List.of(base, label, Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> { + labelColor.update(delta); + label.color(labelColor.value().getColor()); + }))); } } 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 883b778e2..fc0e561c1 100755 --- a/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json +++ b/runtime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json @@ -246,12 +246,19 @@ "config.rei.options.groups.appearance.interface": "Interface", "config.rei.options.appearance.theme": "Theme", "config.rei.options.appearance.theme.desc": "The global theme of Roughly Enough Items. This will be applied everywhere, including background, buttons, etc.", + "config.rei.value.appearance.theme.light": "Light", + "config.rei.value.appearance.theme.dark": "Dark", "config.rei.options.appearance.recipe_border": "Recipe Border", "config.rei.options.appearance.recipe_border.desc": "The border of each recipe. Default is the preferred REI look.", + "config.rei.value.appearance.recipe_border.default": "Default", + "config.rei.value.appearance.recipe_border.lighter": "Lighter", + "config.rei.value.appearance.recipe_border.none": "Invisible", "config.rei.options.appearance.reduced_motion": "Reduced Motion", "config.rei.options.appearance.reduced_motion.desc": "Disables animation for transitions, menus, hover states, to minimize discomfort caused by vestibular motion triggers.", "config.rei.options.appearance.recipe_lookup_style": "Recipe Lookup Style", - "config.rei.options.appearance.recipe_lookup_style.desc": "The style of how recipes are displayed. Default is for the more classic look, while Composite is for the more informative, villger-like look.", + "config.rei.options.appearance.recipe_lookup_style.desc": "The style of how recipes are displayed. Classic is the default look, while Composite is for the more informative, villger-like look.", + "config.rei.value.appearance.recipe_lookup_style.original": "Classic", + "config.rei.value.appearance.recipe_lookup_style.composite": "Composite", "config.rei.options.groups.appearance.tooltips": "Tooltips", "config.rei.options.appearance.append_mod_names": "Append Mod Names", "config.rei.options.appearance.append_mod_names.desc": "Appends the containing namespace for entries. The appended line will be in italisised light blue.", @@ -264,23 +271,40 @@ "config.rei.options.groups.cheats.cheats": "Cheats", "config.rei.options.cheats.mode": "Mode", "config.rei.options.cheats.mode.desc": "Cheats mode allows you to grab items from the side. This requires operator permission. The /give command would be used as a fallback if REI is not installed on the server.", + "config.rei.value.cheats.mode.when_creative": "When Creative", "config.rei.options.cheats.method": "Method", "config.rei.options.cheats.method.desc": "The way how cheating is achieved. Grab mode places the cheated item at your cursor, while give mode places the cheated item in your inventory.", + "config.rei.value.cheats.method.grab": "Grab", + "config.rei.value.cheats.method.give": "Give", "config.rei.options.cheats.amount": "Amount", "config.rei.options.cheats.amount.desc": "The amount of items cheated. By default, REI cheats 1 item and a stack when clicked with shift.", + "config.rei.value.cheats.amount.default": "Default", + "config.rei.value.cheats.amount.reversed": "Reversed", "config.rei.options.groups.cheats.advanced": "Advanced", "config.rei.options.cheats.give_command": "Give Command", "config.rei.options.cheats.give_command.desc": "The command invoked to cheat items when REI is not installed on the server. This may be useful if the server replaced the default /give command. Available placeholders: {item_name}, {item_identifier}, {count} and {player_name}.", "config.rei.options.groups.layout.widgets": "Widgets", "config.rei.options.layout.search_field_location": "Search Field Location", "config.rei.options.layout.search_field_location.desc": "The location of the search field. By default, the search field is placed at the bottom center, which automatically moves to the side to make way for tall container screens.", + "config.rei.value.layout.search_field_location.center": "Center", + "config.rei.value.layout.search_field_location.bottom_left": "Bottom Left", + "config.rei.value.layout.search_field_location.bottom_right": "Bottom Right", + "config.rei.value.layout.search_field_location.top_left": "Top Left", + "config.rei.value.layout.search_field_location.top_right": "Top Right", "config.rei.options.layout.config_button_location": "Config Button Location", "config.rei.options.layout.config_button_location.desc": "The location of the configuration button. By default, it is placed next to the search field. However, this can be changed to look like the legacy versions of REI, where it is placed on the top side of the screen.", + "config.rei.value.layout.config_button_location.next_to_search": "Next to Search Field", + "config.rei.value.layout.config_button_location.top_left": "Top Left", + "config.rei.value.layout.config_button_location.top_right": "Top Right", "config.rei.options.layout.craftable_filter": "Craftable Filter", "config.rei.options.layout.craftable_filter.desc": "Craftable Filter allows you to view stacks currently craftable with the ingredients in your inventory. This can be useful alongside the Ctrl+Click quick craft feature to craft quickly.", "config.rei.options.groups.layout.panel": "Panel", "config.rei.options.layout.boundaries": "Boundaries", "config.rei.options.layout.boundaries.desc": "Declare the boundaries of the panel. Useful to limit the columns / rows displayed on screen.", + "config.rei.options.layout.location": "Location", + "config.rei.options.layout.location.desc": "Change the location of the panel. The entire REI setup may be mirrored horizontally, including the list and all widgets.", + "config.rei.value.layout.location.left": "Left", + "config.rei.value.layout.location.right": "Right", "config.rei.options.groups.accessibility.display": "Display", "config.rei.options.accessibility.larger_tabs": "Larger Tabs", "config.rei.options.accessibility.larger_tabs.desc": "Increase the size of tabs in recipe viewing screens.", @@ -323,6 +347,10 @@ "config.rei.options.groups.search.appearance": "Appearance", "config.rei.options.search.syntax_highlighting": "Syntax Highlighting", "config.rei.options.search.syntax_highlighting.desc": "Displays different search filters in different colors for easier identification.", + "config.rei.value.search.syntax_highlighting.plain": "Plain", + "config.rei.value.search.syntax_highlighting.plain_underscored": "Underscored", + "config.rei.value.search.syntax_highlighting.colorful": "Colorful", + "config.rei.value.search.syntax_highlighting.colorful_underscored": "Colorful & Underscored", "config.rei.options.groups.search.filters": "Filters", "config.rei.options.search.mod_search": "Mod Search", "config.rei.options.search.mod_search.desc": "Filter entries by its containing mod §l%s§r.", @@ -332,6 +360,9 @@ "config.rei.options.search.tag_search.desc": "Filter entries by the tags it is contained in §l%s§r.", "config.rei.options.search.identifier_search": "Identifier Search", "config.rei.options.search.identifier_search.desc": "Filter entries by its identifier §l%s§r.", + "config.rei.value.search.filters.always": "Always Active", + "config.rei.value.search.filters.prefix": "Activate with Prefix", + "config.rei.value.search.filters.never": "Always Inactive", "config.rei.options.groups.search.advanced": "Advanced", "config.rei.options.search.async_search": "Async Search", "config.rei.options.search.async_search.desc": "Parallelize search with multiple threads. This usually improves performance and \"snappiness\" of search.", @@ -351,6 +382,12 @@ "config.rei.value.list.display_mode.paginated": "Paginated", "config.rei.options.list.ordering": "Ordering", "config.rei.options.list.ordering.desc": "The method the entries are sorted by. By default, REI follows the order in which entries are registered into the game. This can be changed to mimic the creative tabs or the direction of the sorting.", + "config.rei.value.list.ordering.registry_ascending": "By Registry", + "config.rei.value.list.ordering.name_ascending": "By Name", + "config.rei.value.list.ordering.groups_ascending": "By Groups", + "config.rei.value.list.ordering.registry_descending": "By Registry (Descending)", + "config.rei.value.list.ordering.name_descending": "By Name (Descending)", + "config.rei.value.list.ordering.groups_descending": "By Groups (Descending)", "config.rei.options.list.zoom": "Zoom", "config.rei.options.list.zoom.desc": "The size of the entries. Increasing the zoom amount may also improve performance as less entries are on the screen at the same time.", "config.rei.options.list.focus_mode": "Focus Mode", -- cgit