aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/dev/isxander/yacl/api/Option.java20
-rw-r--r--src/main/java/dev/isxander/yacl/gui/OptionListWidget.java14
-rw-r--r--src/main/java/dev/isxander/yacl/gui/RequireRestartScreen.java16
-rw-r--r--src/main/java/dev/isxander/yacl/gui/YACLScreen.java10
-rw-r--r--src/main/java/dev/isxander/yacl/gui/controllers/LabelController.java14
-rw-r--r--src/main/java/dev/isxander/yacl/impl/ButtonOptionImpl.java5
-rw-r--r--src/main/java/dev/isxander/yacl/impl/OptionImpl.java8
-rw-r--r--src/main/resources/assets/yet-another-config-lib/lang/en_us.json7
-rw-r--r--src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java1
9 files changed, 74 insertions, 21 deletions
diff --git a/src/main/java/dev/isxander/yacl/api/Option.java b/src/main/java/dev/isxander/yacl/api/Option.java
index a353ae4..ced0772 100644
--- a/src/main/java/dev/isxander/yacl/api/Option.java
+++ b/src/main/java/dev/isxander/yacl/api/Option.java
@@ -52,6 +52,11 @@ public interface Option<T> {
boolean changed();
/**
+ * If true, modifying this option recommends a restart.
+ */
+ boolean requiresRestart();
+
+ /**
* Value in the GUI, ready to set the actual bound value or be undone.
*/
@NotNull T pendingValue();
@@ -96,6 +101,8 @@ public interface Option<T> {
private Binding<T> binding;
+ private boolean requiresRestart;
+
private final Class<T> typeClass;
private Builder(Class<T> typeClass) {
@@ -122,7 +129,7 @@ public interface Option<T> {
* @param tooltips text lines - merged with a new-line on {@link Builder#build()}.
*/
public Builder<T> tooltip(@NotNull Text... tooltips) {
- Validate.notEmpty(tooltips, "`tooltips` cannot be empty");
+ Validate.notNull(tooltips, "`tooltips` cannot be empty");
tooltipLines.addAll(List.of(tooltips));
return this;
@@ -172,6 +179,15 @@ public interface Option<T> {
return this;
}
+ /**
+ * Dictates whether the option should require a restart.
+ * {@link Option#requiresRestart()}
+ */
+ public Builder<T> requiresRestart(boolean requiresRestart) {
+ this.requiresRestart = requiresRestart;
+ return this;
+ }
+
public Option<T> build() {
Validate.notNull(controlGetter, "`control` must not be null when building `Option`");
Validate.notNull(binding, "`binding` must not be null when building `Option`");
@@ -185,7 +201,7 @@ public interface Option<T> {
concatenatedTooltip.append(line);
}
- return new OptionImpl<>(name, concatenatedTooltip, controlGetter, binding, typeClass);
+ return new OptionImpl<>(name, concatenatedTooltip, controlGetter, binding, requiresRestart, typeClass);
}
}
}
diff --git a/src/main/java/dev/isxander/yacl/gui/OptionListWidget.java b/src/main/java/dev/isxander/yacl/gui/OptionListWidget.java
index c1c1f10..804592d 100644
--- a/src/main/java/dev/isxander/yacl/gui/OptionListWidget.java
+++ b/src/main/java/dev/isxander/yacl/gui/OptionListWidget.java
@@ -7,6 +7,7 @@ import dev.isxander.yacl.api.OptionGroup;
import dev.isxander.yacl.api.utils.Dimension;
import dev.isxander.yacl.impl.YACLConstants;
import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.font.MultilineText;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.Selectable;
@@ -235,7 +236,7 @@ public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry>
private class GroupSeparatorEntry extends Entry {
private final OptionGroup group;
- private final List<OrderedText> wrappedName;
+ private final MultilineText wrappedName;
private final List<OrderedText> wrappedTooltip;
private final ButtonWidget expandMinimizeButton;
@@ -251,7 +252,8 @@ public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry>
public GroupSeparatorEntry(OptionGroup group, Screen screen) {
this.group = group;
this.screen = screen;
- this.wrappedName = textRenderer.wrapLines(group.name(), getRowWidth() - 45);
+ this.wrappedName = MultilineText.create(textRenderer, group.name(), getRowWidth() - 45);
+ //this.wrappedName = textRenderer.wrapLines(group.name(), getRowWidth() - 45);
this.wrappedTooltip = textRenderer.wrapLines(group.tooltip(), screen.width / 2);
this.groupExpanded = !group.collapsed();
this.expandMinimizeButton = new ButtonWidget(0, 0, 20, 20, Text.empty(), btn -> {
@@ -274,11 +276,7 @@ public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry>
else
hoveredTicks = 0;
- int i = 0;
- for (OrderedText line : wrappedName) {
- textRenderer.drawWithShadow(matrices, line, x + entryWidth / 2f - textRenderer.getWidth(line) / 2f, y + getYPadding() + i * textRenderer.fontHeight, -1);
- i++;
- }
+ wrappedName.drawCenterWithShadow(matrices, x + entryWidth / 2, y + getYPadding());
if (hoveredTicks >= YACLConstants.HOVER_TICKS) {
screen.renderOrderedTooltip(matrices, wrappedTooltip, x - 6, y + entryHeight / 2 + 6 + (wrappedTooltip.size() * textRenderer.fontHeight) / 2);
@@ -298,7 +296,7 @@ public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry>
@Override
public int getItemHeight() {
- return wrappedName.size() * textRenderer.fontHeight + getYPadding() * 2;
+ return wrappedName.count() * textRenderer.fontHeight + getYPadding() * 2;
}
private int getYPadding() {
diff --git a/src/main/java/dev/isxander/yacl/gui/RequireRestartScreen.java b/src/main/java/dev/isxander/yacl/gui/RequireRestartScreen.java
new file mode 100644
index 0000000..807292e
--- /dev/null
+++ b/src/main/java/dev/isxander/yacl/gui/RequireRestartScreen.java
@@ -0,0 +1,16 @@
+package dev.isxander.yacl.gui;
+
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.screen.ConfirmScreen;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.text.Text;
+import net.minecraft.util.Formatting;
+
+public class RequireRestartScreen extends ConfirmScreen {
+ protected RequireRestartScreen(Screen parent) {
+ super(option -> {
+ if (option) MinecraftClient.getInstance().scheduleStop();
+ else MinecraftClient.getInstance().setScreen(parent);
+ }, Text.translatable("yacl.restart.title").formatted(Formatting.RED, Formatting.BOLD), Text.translatable("yacl.restart.message"), Text.translatable("yacl.restart.yes"), Text.translatable("yacl.restart.no"));
+ }
+}
diff --git a/src/main/java/dev/isxander/yacl/gui/YACLScreen.java b/src/main/java/dev/isxander/yacl/gui/YACLScreen.java
index ccd3929..986a4f6 100644
--- a/src/main/java/dev/isxander/yacl/gui/YACLScreen.java
+++ b/src/main/java/dev/isxander/yacl/gui/YACLScreen.java
@@ -69,7 +69,12 @@ public class YACLScreen extends Screen {
saveButtonMessage = null;
if (pendingChanges()) {
- OptionUtils.forEachOptions(config, Option::applyValue);
+ AtomicBoolean requiresRestart = new AtomicBoolean(false);
+ OptionUtils.forEachOptions(config, option -> {
+ if (option.requiresRestart())
+ requiresRestart.set(true);
+ option.applyValue();
+ });
OptionUtils.forEachOptions(config, option -> {
if (option.changed()) {
YACLConstants.LOGGER.error("Option '{}' was saved as '{}' but the changes don't seem to have applied.", option.name().getString(), option.pendingValue());
@@ -77,6 +82,9 @@ public class YACLScreen extends Screen {
}
});
config.saveFunction().run();
+ if (requiresRestart.get()) {
+ client.setScreen(new RequireRestartScreen(this));
+ }
} else close();
});
actionDim.expand(-actionDim.width() / 2 - 2, 0).move(-actionDim.width() / 2 - 2, -22);
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/LabelController.java b/src/main/java/dev/isxander/yacl/gui/controllers/LabelController.java
index 07ee8da..13687e0 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/LabelController.java
+++ b/src/main/java/dev/isxander/yacl/gui/controllers/LabelController.java
@@ -5,8 +5,8 @@ import dev.isxander.yacl.api.Option;
import dev.isxander.yacl.api.utils.Dimension;
import dev.isxander.yacl.gui.AbstractWidget;
import dev.isxander.yacl.gui.YACLScreen;
+import net.minecraft.client.font.MultilineText;
import net.minecraft.client.util.math.MatrixStack;
-import net.minecraft.text.OrderedText;
import net.minecraft.text.Text;
import org.jetbrains.annotations.ApiStatus;
@@ -46,7 +46,7 @@ public class LabelController implements Controller<Text> {
@ApiStatus.Internal
public class LabelControllerElement extends AbstractWidget {
- private List<OrderedText> wrappedText;
+ private MultilineText wrappedText;
public LabelControllerElement(Dimension<Integer> dim) {
super(dim);
@@ -57,11 +57,7 @@ public class LabelController implements Controller<Text> {
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
updateText();
- int i = 0;
- for (OrderedText text : wrappedText) {
- textRenderer.drawWithShadow(matrices, text, dim.x(), dim.y() + getYPadding() + i * textRenderer.fontHeight, -1);
- i++;
- }
+ wrappedText.drawWithShadow(matrices, dim.x(), dim.y() + getYPadding(), textRenderer.fontHeight, -1);
}
private int getYPadding() {
@@ -69,8 +65,8 @@ public class LabelController implements Controller<Text> {
}
private void updateText() {
- wrappedText = textRenderer.wrapLines(formatValue(), dim.width());
- dim.setHeight(wrappedText.size() * 9 + getYPadding() * 2);
+ wrappedText = MultilineText.create(textRenderer, formatValue(), dim.width());
+ dim.setHeight(wrappedText.count() * textRenderer.fontHeight + getYPadding() * 2);
}
}
}
diff --git a/src/main/java/dev/isxander/yacl/impl/ButtonOptionImpl.java b/src/main/java/dev/isxander/yacl/impl/ButtonOptionImpl.java
index d3fbaa6..b531dec 100644
--- a/src/main/java/dev/isxander/yacl/impl/ButtonOptionImpl.java
+++ b/src/main/java/dev/isxander/yacl/impl/ButtonOptionImpl.java
@@ -64,6 +64,11 @@ public class ButtonOptionImpl implements ButtonOption {
}
@Override
+ public boolean requiresRestart() {
+ return false;
+ }
+
+ @Override
public boolean changed() {
return false;
}
diff --git a/src/main/java/dev/isxander/yacl/impl/OptionImpl.java b/src/main/java/dev/isxander/yacl/impl/OptionImpl.java
index 2d66aee..d63f20b 100644
--- a/src/main/java/dev/isxander/yacl/impl/OptionImpl.java
+++ b/src/main/java/dev/isxander/yacl/impl/OptionImpl.java
@@ -16,6 +16,7 @@ public class OptionImpl<T> implements Option<T> {
private final Text tooltip;
private final Controller<T> controller;
private final Binding<T> binding;
+ private final boolean requiresRestart;
private final Class<T> typeClass;
@@ -26,12 +27,14 @@ public class OptionImpl<T> implements Option<T> {
@Nullable Text tooltip,
@NotNull Function<Option<T>, Controller<T>> controlGetter,
@NotNull Binding<T> binding,
+ boolean requiresRestart,
@NotNull Class<T> typeClass
) {
this.name = name;
this.tooltip = tooltip;
this.controller = controlGetter.apply(this);
this.binding = binding;
+ this.requiresRestart = requiresRestart;
this.typeClass = typeClass;
this.pendingValue = binding().getValue();
}
@@ -62,6 +65,11 @@ public class OptionImpl<T> implements Option<T> {
}
@Override
+ public boolean requiresRestart() {
+ return requiresRestart;
+ }
+
+ @Override
public boolean changed() {
return !binding().getValue().equals(pendingValue);
}
diff --git a/src/main/resources/assets/yet-another-config-lib/lang/en_us.json b/src/main/resources/assets/yet-another-config-lib/lang/en_us.json
index 6510d86..4057fa0 100644
--- a/src/main/resources/assets/yet-another-config-lib/lang/en_us.json
+++ b/src/main/resources/assets/yet-another-config-lib/lang/en_us.json
@@ -15,5 +15,10 @@
"yacl.gui.fail_apply": "Failed to apply",
"yacl.gui.fail_apply.tooltip": "There was an error and the changes couldn't be applied.",
"yacl.gui.save_before_exit": "Save before exiting!",
- "yacl.gui.save_before_exit.tooltip": "Save or cancel to exit the GUI."
+ "yacl.gui.save_before_exit.tooltip": "Save or cancel to exit the GUI.",
+
+ "yacl.restart.title": "Config requires restart!",
+ "yacl.restart.message": "One or more options needs you to restart the game to apply the changes.",
+ "yacl.restart.yes": "Close Minecraft",
+ "yacl.restart.no": "Ignore"
}
diff --git a/src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java b/src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java
index 23c9b7e..9fd7d46 100644
--- a/src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java
+++ b/src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java
@@ -62,6 +62,7 @@ public class ModMenuIntegration implements ModMenuApi {
(value) -> TestSettings.booleanToggle = value
)
.controller(BooleanController::new)
+ .requiresRestart(true)
.build())
.option(Option.createBuilder(boolean.class)
.name(Text.of("Custom Boolean Toggle"))