aboutsummaryrefslogtreecommitdiff
path: root/runtime/src
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2023-10-26 15:49:00 +0800
committershedaniel <daniel@shedaniel.me>2024-04-16 00:38:18 +0900
commit598dfc5c1f5e532a34f09c7d8d398ec727a33ab3 (patch)
tree2f41015d23de0e2a18fce460619a9aeb40aceb36 /runtime/src
parent881f8d146f15c2dfbe1292747f933d3c19cb429a (diff)
downloadRoughlyEnoughItems-598dfc5c1f5e532a34f09c7d8d398ec727a33ab3.tar.gz
RoughlyEnoughItems-598dfc5c1f5e532a34f09c7d8d398ec727a33ab3.tar.bz2
RoughlyEnoughItems-598dfc5c1f5e532a34f09c7d8d398ec727a33ab3.zip
Localise more values and add a basic theme previewer
Diffstat (limited to 'runtime/src')
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigEntriesListWidget.java1
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigGroupWidget.java57
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigOptionValueWidget.java6
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigOptionWidget.java58
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigGroups.java3
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/AllREIConfigOptions.java24
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/CompositeOption.java18
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/OptionValueEntry.java38
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/options/preview/ThemePreviewer.java17
-rwxr-xr-xruntime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json39
10 files changed, 222 insertions, 39 deletions
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<Widget> widgets = new ArrayList<>();
- int height = 0;
+ List<Triple<Widget, Supplier<Rectangle>, 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<Widget, Supplier<Rectangle>, 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<CompositeOption<?>, 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 <T> WidgetWithBounds create(CompositeOption<T> option, int width) {
List<Widget> 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<FormattedCharSequence> 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<Float> 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<? extends GuiEventListener> 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<Boolean> REDUCED_MOTION = make("appearance.reduced_motion", i -> i.basics.reduceMotion, (i, v) -> i.basics.reduceMotion = v)
.enabledDisabled();
CompositeOption<DisplayScreenType> 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<Boolean> APPEND_MOD_NAMES = make("appearance.append_mod_names", i -> i.advanced.tooltips.appendModNames, (i, v) -> i.advanced.tooltips.appendModNames = v)
.enabledDisabled();
CompositeOption<Boolean> 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<String> GIVE_COMMAND = make("cheats.give_command", i -> i.advanced.commands.giveCommand, (i, v) -> i.advanced.commands.giveCommand = v);
CompositeOption<SearchFieldLocation> SEARCH_FIELD_LOCATION = make("layout.search_field_location", i -> i.appearance.layout.searchFieldLocation, (i, v) -> i.appearance.layout.searchFieldLocation = v)
- .enumOptions();
+ .entry(OptionValueEntry.<SearchFieldLocation>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<ConfigButtonPosition> CONFIG_BUTTON_LOCATION = make("layout.config_button_location", i -> i.appearance.layout.configButtonLocation, (i, v) -> i.appearance.layout.configButtonLocation = v)
- .enumOptions();
+ .entry(OptionValueEntry.<ConfigButtonPosition>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<Boolean> CRAFTABLE_FILTER = make("layout.craftable_filter", i -> i.appearance.layout.showCraftableOnlyButton, (i, v) -> i.appearance.layout.showCraftableOnlyButton = v)
.enabledDisabled();
// TODO: BOUNDARIES
CompositeOption<Boolean> BOUNDARIES = make("layout.boundaries", i -> true, (i, v) -> {
});
+ CompositeOption<DisplayPanelLocation> LOCATION = make("layout.location", i -> i.advanced.accessibility.displayPanelLocation, (i, v) -> i.advanced.accessibility.displayPanelLocation = v)
+ .enumOptions();
CompositeOption<Boolean> LARGER_TABS = make("accessibility.larger_tabs", i -> !i.advanced.accessibility.useCompactTabs, (i, v) -> i.advanced.accessibility.useCompactTabs = !v)
.enabledDisabled();
CompositeOption<Boolean> 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<T> {
private final Component name;
@@ -37,6 +38,8 @@ public class CompositeOption<T> {
private final BiConsumer<ConfigObjectImpl, T> save;
@Nullable
private ConfigPreviewer<T> previewer;
+ @Nullable
+ private Supplier<T> defaultValue = null;
private OptionValueEntry<T> entry;
public CompositeOption(Component name, Component description, Function<ConfigObjectImpl, T> bind, BiConsumer<ConfigObjectImpl, T> save) {
@@ -67,11 +70,20 @@ public class CompositeOption<T> {
return this.entry(OptionValueEntry.enumOptions(entry));
}
+ public CompositeOption<T> options(T... entry) {
+ return this.entry(OptionValueEntry.options(entry));
+ }
+
public CompositeOption<T> previewer(ConfigPreviewer<T> previewer) {
this.previewer = previewer;
return this;
}
+ public CompositeOption<T> defaultValue(Supplier<T> defaultValue) {
+ this.defaultValue = defaultValue;
+ return this;
+ }
+
public Component getName() {
return name;
}
@@ -100,4 +112,10 @@ public class CompositeOption<T> {
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<T> {
};
}
- static OptionValueEntry<Boolean> ofBoolean(Component falseText, Component trueText) {
+ static OptionValueEntry.Selection<Boolean> ofBoolean(Component falseText, Component trueText) {
return new Selection<Boolean>() {
@Override
public List<Boolean> getOptions() {
@@ -51,17 +53,17 @@ public interface OptionValueEntry<T> {
};
}
- static OptionValueEntry<Boolean> trueFalse() {
+ static OptionValueEntry.Selection<Boolean> trueFalse() {
return ofBoolean(translatable("config.rei.value.trueFalse.false"),
translatable("config.rei.value.trueFalse.true"));
}
- static OptionValueEntry<Boolean> enabledDisabled() {
+ static OptionValueEntry.Selection<Boolean> enabledDisabled() {
return ofBoolean(translatable("config.rei.value.enabledDisabled.false"),
translatable("config.rei.value.enabledDisabled.true"));
}
- static <T> OptionValueEntry<T> enumOptions(T... array) {
+ static <T> OptionValueEntry.Selection<T> enumOptions(T... array) {
Class<T> type = (Class<T>) array.getClass().getComponentType();
Object[] constants = type.getEnumConstants();
return new Selection<T>() {
@@ -77,9 +79,37 @@ public interface OptionValueEntry<T> {
};
}
+ static <T> OptionValueEntry<T> options(T... options) {
+ return new Selection<T>() {
+ @Override
+ public List<T> getOptions() {
+ return Arrays.asList(options);
+ }
+
+ @Override
+ public Component getOption(T value) {
+ return literal(value.toString());
+ }
+ };
+ }
+
interface Selection<T> extends OptionValueEntry<T> {
List<T> getOptions();
Component getOption(T value);
+
+ default Selection<T> overrideText(Function<T, Component> textFunction) {
+ return new Selection<T>() {
+ @Override
+ public List<T> 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<AppearanceTheme> {
@Override
public WidgetWithBounds preview(int width, Supplier<AppearanceTheme> 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<Color> 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.l