aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--build.gradle.kts26
-rw-r--r--changelogs/2.0.0.md7
-rw-r--r--gradle.properties5
-rw-r--r--src/client/java/dev/isxander/yacl/api/Binding.java (renamed from src/main/java/dev/isxander/yacl/api/Binding.java)2
-rw-r--r--src/client/java/dev/isxander/yacl/api/ButtonOption.java (renamed from src/main/java/dev/isxander/yacl/api/ButtonOption.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/api/ConfigCategory.java (renamed from src/main/java/dev/isxander/yacl/api/ConfigCategory.java)1
-rw-r--r--src/client/java/dev/isxander/yacl/api/Controller.java (renamed from src/main/java/dev/isxander/yacl/api/Controller.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/api/NameableEnum.java (renamed from src/main/java/dev/isxander/yacl/api/NameableEnum.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/api/Option.java (renamed from src/main/java/dev/isxander/yacl/api/Option.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/api/OptionFlag.java (renamed from src/main/java/dev/isxander/yacl/api/OptionFlag.java)8
-rw-r--r--src/client/java/dev/isxander/yacl/api/OptionGroup.java (renamed from src/main/java/dev/isxander/yacl/api/OptionGroup.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/api/PlaceholderCategory.java (renamed from src/main/java/dev/isxander/yacl/api/PlaceholderCategory.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/api/YetAnotherConfigLib.java (renamed from src/main/java/dev/isxander/yacl/api/YetAnotherConfigLib.java)15
-rw-r--r--src/client/java/dev/isxander/yacl/api/utils/OptionUtils.java (renamed from src/main/java/dev/isxander/yacl/api/utils/OptionUtils.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/gui/AbstractWidget.java (renamed from src/main/java/dev/isxander/yacl/gui/AbstractWidget.java)10
-rw-r--r--src/client/java/dev/isxander/yacl/gui/CategoryListWidget.java (renamed from src/main/java/dev/isxander/yacl/gui/CategoryListWidget.java)22
-rw-r--r--src/client/java/dev/isxander/yacl/gui/CategoryWidget.java (renamed from src/main/java/dev/isxander/yacl/gui/CategoryWidget.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/gui/ElementListWidgetExt.java152
-rw-r--r--src/client/java/dev/isxander/yacl/gui/LowProfileButtonWidget.java (renamed from src/main/java/dev/isxander/yacl/gui/LowProfileButtonWidget.java)10
-rw-r--r--src/client/java/dev/isxander/yacl/gui/OptionListWidget.java (renamed from src/main/java/dev/isxander/yacl/gui/OptionListWidget.java)133
-rw-r--r--src/client/java/dev/isxander/yacl/gui/RequireRestartScreen.java (renamed from src/main/java/dev/isxander/yacl/gui/RequireRestartScreen.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/gui/SearchFieldWidget.java (renamed from src/main/java/dev/isxander/yacl/gui/SearchFieldWidget.java)2
-rw-r--r--src/client/java/dev/isxander/yacl/gui/TextScaledButtonWidget.java (renamed from src/main/java/dev/isxander/yacl/gui/TextScaledButtonWidget.java)11
-rw-r--r--src/client/java/dev/isxander/yacl/gui/TooltipButtonWidget.java (renamed from src/main/java/dev/isxander/yacl/gui/TooltipButtonWidget.java)4
-rw-r--r--src/client/java/dev/isxander/yacl/gui/YACLScreen.java (renamed from src/main/java/dev/isxander/yacl/gui/YACLScreen.java)39
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/ActionController.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/ActionController.java)4
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/BooleanController.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/BooleanController.java)14
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/ColorController.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/ColorController.java)27
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java)4
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/LabelController.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/LabelController.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/TickBoxController.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/TickBoxController.java)11
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/cycling/CyclingControllerElement.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/cycling/CyclingControllerElement.java)8
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/cycling/CyclingListController.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/cycling/CyclingListController.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/cycling/EnumController.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/cycling/EnumController.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/cycling/ICyclingController.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/cycling/ICyclingController.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/package-info.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/package-info.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/slider/DoubleSliderController.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/slider/DoubleSliderController.java)2
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/slider/FloatSliderController.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/slider/FloatSliderController.java)2
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/slider/ISliderController.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/slider/ISliderController.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/slider/IntegerSliderController.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/slider/IntegerSliderController.java)2
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/slider/LongSliderController.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/slider/LongSliderController.java)2
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/slider/SliderControllerElement.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/slider/SliderControllerElement.java)6
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/slider/package-info.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/slider/package-info.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/string/IStringController.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/string/IStringController.java)12
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/string/StringController.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/string/StringController.java)5
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/string/StringControllerElement.java (renamed from src/main/java/dev/isxander/yacl/gui/controllers/string/StringControllerElement.java)117
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/string/number/DoubleFieldController.java105
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/string/number/FloatFieldController.java105
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/string/number/IntegerFieldController.java109
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/string/number/LongFieldController.java109
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/string/number/NumberFieldController.java69
-rw-r--r--src/client/java/dev/isxander/yacl/gui/controllers/string/number/package-info.java10
-rw-r--r--src/client/java/dev/isxander/yacl/impl/ButtonOptionImpl.java (renamed from src/main/java/dev/isxander/yacl/impl/ButtonOptionImpl.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/impl/ConfigCategoryImpl.java (renamed from src/main/java/dev/isxander/yacl/impl/ConfigCategoryImpl.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/impl/GenericBindingImpl.java (renamed from src/main/java/dev/isxander/yacl/impl/GenericBindingImpl.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/impl/OptionGroupImpl.java (renamed from src/main/java/dev/isxander/yacl/impl/OptionGroupImpl.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/impl/OptionImpl.java (renamed from src/main/java/dev/isxander/yacl/impl/OptionImpl.java)1
-rw-r--r--src/client/java/dev/isxander/yacl/impl/PlaceholderCategoryImpl.java (renamed from src/main/java/dev/isxander/yacl/impl/PlaceholderCategoryImpl.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/impl/YetAnotherConfigLibImpl.java (renamed from src/main/java/dev/isxander/yacl/impl/YetAnotherConfigLibImpl.java)0
-rw-r--r--src/client/java/dev/isxander/yacl/mixin/client/SimpleOptionAccessor.java (renamed from src/main/java/dev/isxander/yacl/mixin/SimpleOptionAccessor.java)2
-rw-r--r--src/client/resources/yet-another-config-lib.client.mixins.json (renamed from src/main/resources/yet-another-config-lib.mixins.json)2
-rw-r--r--src/main/java/dev/isxander/yacl/config/ConfigInstance.java14
-rw-r--r--src/main/java/dev/isxander/yacl/gui/controllers/EnumController.java35
-rw-r--r--src/main/resources/fabric.mod.json12
-rw-r--r--src/testmod/java/dev/isxander/yacl/test/GuiTest.java (renamed from src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java)191
-rw-r--r--src/testmod/java/dev/isxander/yacl/test/config/ConfigData.java4
-rw-r--r--src/testmod/java/dev/isxander/yacl/test/config/Entrypoint.java3
-rw-r--r--src/testmod/java/dev/isxander/yacl/test/mixins/TitleScreenMixin.java26
-rw-r--r--src/testmod/resources/fabric.mod.json13
-rw-r--r--src/testmod/resources/yet-another-config-lib.test.mixins.json11
71 files changed, 1085 insertions, 401 deletions
diff --git a/README.md b/README.md
index e7882ee..f6b2bf8 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,7 @@ Yet Another Config Lib, like, what were you expecting?
This mod was made to fill a hole in this area of Fabric modding. The existing main config libraries don't achieve what I want from them:
-- **[Cloth Config API](https://modrinth.com/mod/cloth-config)**:<br/>**It's stale.** The developer of cloth has clarified that they are likely not going to add any more features. They don't want to touch it.
+- **[Cloth Config API](https://modrinth.com/mod/cloth-config)**:<br/>**It's stale.** The developer of cloth has clarified that they are likely not going to add any more features. They don't want to touch it. ([citation](https://user-images.githubusercontent.com/43245524/206530322-3ae46008-5356-468e-9a73-63b859364d4e.png))
- **[SpruceUI](https://github.com/LambdAurora/SpruceUI)**:<br/>**It isn't designed for configuration.** In this essence the design feels cluttered. Further details available in [this issue](https://github.com/isXander/Zoomify/issues/85).
- **[MidnightLib](https://modrinth.com/mod/midnightlib)**:<br/>**It has cosmetics among other utilities.** It may not be large but some players (including me) wouldn't want cosmetics out of nowhere.
- **[OwoLib](https://modrinth.com/mod/owo-lib)**:<br/>**It's content focused.** It does a lot of other things as well as config, adding to the size.
diff --git a/build.gradle.kts b/build.gradle.kts
index 6655cbb..7fa93c3 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -2,7 +2,7 @@ plugins {
java
id("fabric-loom") version "1.0.+"
- id("io.github.juuxel.loom-quiltflower") version "1.7.+"
+ id("io.github.juuxel.loom-quiltflower") version "1.8.+"
id("com.modrinth.minotaur") version "2.4.+"
id("me.hypherionmc.cursegradle") version "2.+"
@@ -16,14 +16,27 @@ plugins {
val ciRun = System.getenv().containsKey("GITHUB_ACTIONS")
group = "dev.isxander"
-version = "1.7.1"
+version = "2.0.0"
if (ciRun)
version = "$version+${grgit.branch.current().name}-SNAPSHOT"
+loom {
+ splitEnvironmentSourceSets()
+
+ mods {
+ register("yet-another-config-lib") {
+ sourceSet(sourceSets["main"])
+ sourceSet(sourceSets["client"])
+ }
+ }
+}
+
val testmod by sourceSets.registering {
compileClasspath += sourceSets.main.get().compileClasspath
runtimeClasspath += sourceSets.main.get().runtimeClasspath
+ compileClasspath += sourceSets["client"].compileClasspath
+ runtimeClasspath += sourceSets["client"].runtimeClasspath
}
loom {
@@ -48,18 +61,17 @@ repositories {
val minecraftVersion: String by project
val fabricLoaderVersion: String by project
+val yarnBuild: String by project
dependencies {
minecraft("com.mojang:minecraft:$minecraftVersion")
- mappings("net.fabricmc:yarn:$minecraftVersion+build.+:v2")
+ mappings("net.fabricmc:yarn:$minecraftVersion+build.$yarnBuild:v2")
modImplementation("net.fabricmc:fabric-loader:$fabricLoaderVersion")
- modImplementation(fabricApi.module("fabric-resource-loader-v0", "0.66.0+1.19.2"))
+ "modClientImplementation"(fabricApi.module("fabric-resource-loader-v0", "0.68.1+1.19.3"))
"testmodImplementation"(sourceSets.main.get().output)
- "modTestmodImplementation"("com.terraformersmc:modmenu:4.0.6") {
- exclude(module = "fabric-loader")
- }
+ "testmodImplementation"(sourceSets["client"].output)
}
java {
diff --git a/changelogs/2.0.0.md b/changelogs/2.0.0.md
new file mode 100644
index 0000000..b56d0b1
--- /dev/null
+++ b/changelogs/2.0.0.md
@@ -0,0 +1,7 @@
+- Update to 1.19.3
+- Colour field controllers
+- Better carot positioning when clicking in text fields
+- Better text selection for text fields
+- Smooth scrolling for category list
+- Fix category list scrollbar appearing under option list background in-game
+- Fix tick box name text length limiting
diff --git a/gradle.properties b/gradle.properties
index 0f0b15f..292f0c1 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,7 +1,8 @@
org.gradle.jvmargs=-Xmx3G
-minecraftVersion=1.19.2
-fabricLoaderVersion=0.14.10
+minecraftVersion=1.19.3
+fabricLoaderVersion=0.14.11
+yarnBuild=1
modId=yet-another-config-lib
modName=YetAnotherConfigLib
diff --git a/src/main/java/dev/isxander/yacl/api/Binding.java b/src/client/java/dev/isxander/yacl/api/Binding.java
index 395beb2..91158d3 100644
--- a/src/main/java/dev/isxander/yacl/api/Binding.java
+++ b/src/client/java/dev/isxander/yacl/api/Binding.java
@@ -1,7 +1,7 @@
package dev.isxander.yacl.api;
import dev.isxander.yacl.impl.GenericBindingImpl;
-import dev.isxander.yacl.mixin.SimpleOptionAccessor;
+import dev.isxander.yacl.mixin.client.SimpleOptionAccessor;
import net.minecraft.client.option.SimpleOption;
import org.apache.commons.lang3.Validate;
diff --git a/src/main/java/dev/isxander/yacl/api/ButtonOption.java b/src/client/java/dev/isxander/yacl/api/ButtonOption.java
index 1124a9a..1124a9a 100644
--- a/src/main/java/dev/isxander/yacl/api/ButtonOption.java
+++ b/src/client/java/dev/isxander/yacl/api/ButtonOption.java
diff --git a/src/main/java/dev/isxander/yacl/api/ConfigCategory.java b/src/client/java/dev/isxander/yacl/api/ConfigCategory.java
index 27c3e95..e9755dd 100644
--- a/src/main/java/dev/isxander/yacl/api/ConfigCategory.java
+++ b/src/client/java/dev/isxander/yacl/api/ConfigCategory.java
@@ -11,7 +11,6 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import java.util.function.Function;
/**
* Separates {@link Option}s or {@link OptionGroup}s into multiple distinct sections.
diff --git a/src/main/java/dev/isxander/yacl/api/Controller.java b/src/client/java/dev/isxander/yacl/api/Controller.java
index 7bf7e7f..7bf7e7f 100644
--- a/src/main/java/dev/isxander/yacl/api/Controller.java
+++ b/src/client/java/dev/isxander/yacl/api/Controller.java
diff --git a/src/main/java/dev/isxander/yacl/api/NameableEnum.java b/src/client/java/dev/isxander/yacl/api/NameableEnum.java
index 793b230..793b230 100644
--- a/src/main/java/dev/isxander/yacl/api/NameableEnum.java
+++ b/src/client/java/dev/isxander/yacl/api/NameableEnum.java
diff --git a/src/main/java/dev/isxander/yacl/api/Option.java b/src/client/java/dev/isxander/yacl/api/Option.java
index 772c816..772c816 100644
--- a/src/main/java/dev/isxander/yacl/api/Option.java
+++ b/src/client/java/dev/isxander/yacl/api/Option.java
diff --git a/src/main/java/dev/isxander/yacl/api/OptionFlag.java b/src/client/java/dev/isxander/yacl/api/OptionFlag.java
index 203a674..7a5c23f 100644
--- a/src/main/java/dev/isxander/yacl/api/OptionFlag.java
+++ b/src/client/java/dev/isxander/yacl/api/OptionFlag.java
@@ -11,14 +11,10 @@ import java.util.function.Consumer;
*/
@FunctionalInterface
public interface OptionFlag extends Consumer<MinecraftClient> {
- /**
- * Warns the user that a game restart is required for the changes to take effect
- */
+ /** Warns the user that a game restart is required for the changes to take effect */
OptionFlag GAME_RESTART = client -> client.setScreen(new RequireRestartScreen(client.currentScreen));
- /**
- * Reloads chunks upon applying (F3+A)
- */
+ /** Reloads chunks upon applying (F3+A) */
OptionFlag RELOAD_CHUNKS = client -> client.worldRenderer.reload();
OptionFlag WORLD_RENDER_UPDATE = client -> client.worldRenderer.scheduleTerrainUpdate();
diff --git a/src/main/java/dev/isxander/yacl/api/OptionGroup.java b/src/client/java/dev/isxander/yacl/api/OptionGroup.java
index 3364bdf..3364bdf 100644
--- a/src/main/java/dev/isxander/yacl/api/OptionGroup.java
+++ b/src/client/java/dev/isxander/yacl/api/OptionGroup.java
diff --git a/src/main/java/dev/isxander/yacl/api/PlaceholderCategory.java b/src/client/java/dev/isxander/yacl/api/PlaceholderCategory.java
index de7441c..de7441c 100644
--- a/src/main/java/dev/isxander/yacl/api/PlaceholderCategory.java
+++ b/src/client/java/dev/isxander/yacl/api/PlaceholderCategory.java
diff --git a/src/main/java/dev/isxander/yacl/api/YetAnotherConfigLib.java b/src/client/java/dev/isxander/yacl/api/YetAnotherConfigLib.java
index a69ae4e..ae6c060 100644
--- a/src/main/java/dev/isxander/yacl/api/YetAnotherConfigLib.java
+++ b/src/client/java/dev/isxander/yacl/api/YetAnotherConfigLib.java
@@ -1,6 +1,7 @@
package dev.isxander.yacl.api;
import com.google.common.collect.ImmutableList;
+import dev.isxander.yacl.config.ConfigInstance;
import dev.isxander.yacl.gui.YACLScreen;
import dev.isxander.yacl.impl.YetAnotherConfigLibImpl;
import net.minecraft.client.gui.screen.Screen;
@@ -12,6 +13,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.function.BiFunction;
import java.util.function.Consumer;
/**
@@ -53,6 +55,14 @@ public interface YetAnotherConfigLib {
return new Builder();
}
+ /**
+ * Creates an instance using a {@link ConfigInstance} which autofills the save() builder method.
+ * This also takes an easy functional interface that provides defaults and config to help build YACL bindings.
+ */
+ static <T> YetAnotherConfigLib create(ConfigInstance<T> configInstance, ConfigBackedBuilder<T> builder) {
+ return builder.build(configInstance.getDefaults(), configInstance.getConfig(), createBuilder().save(configInstance::save)).build();
+ }
+
class Builder {
private Text title;
private final List<ConfigCategory> categories = new ArrayList<>();
@@ -133,4 +143,9 @@ public interface YetAnotherConfigLib {
return new YetAnotherConfigLibImpl(title, ImmutableList.copyOf(categories), saveFunction, initConsumer);
}
}
+
+ @FunctionalInterface
+ interface ConfigBackedBuilder<T> {
+ YetAnotherConfigLib.Builder build(T defaults, T config, YetAnotherConfigLib.Builder builder);
+ }
}
diff --git a/src/main/java/dev/isxander/yacl/api/utils/OptionUtils.java b/src/client/java/dev/isxander/yacl/api/utils/OptionUtils.java
index ab46b5b..ab46b5b 100644
--- a/src/main/java/dev/isxander/yacl/api/utils/OptionUtils.java
+++ b/src/client/java/dev/isxander/yacl/api/utils/OptionUtils.java
diff --git a/src/main/java/dev/isxander/yacl/gui/AbstractWidget.java b/src/client/java/dev/isxander/yacl/gui/AbstractWidget.java
index 03dc9b9..529748d 100644
--- a/src/main/java/dev/isxander/yacl/gui/AbstractWidget.java
+++ b/src/client/java/dev/isxander/yacl/gui/AbstractWidget.java
@@ -15,7 +15,7 @@ import net.minecraft.client.sound.PositionedSoundInstance;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.sound.SoundEvents;
-import java.awt.*;
+import java.awt.Color;
public abstract class AbstractWidget implements Element, Drawable, Selectable {
protected final MinecraftClient client = MinecraftClient.getInstance();
@@ -82,7 +82,7 @@ public abstract class AbstractWidget implements Element, Drawable, Selectable {
int width = x2 - x1;
int height = y2 - y1;
- RenderSystem.setShader(GameRenderer::getPositionTexShader);
+ RenderSystem.setShader(GameRenderer::getPositionTexProgram);
RenderSystem.setShaderTexture(0, ClickableWidget.WIDGETS_TEXTURE);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
int i = !enabled ? 0 : hovered ? 2 : 1;
@@ -96,9 +96,9 @@ public abstract class AbstractWidget implements Element, Drawable, Selectable {
protected int multiplyColor(int hex, float amount) {
Color color = new Color(hex, true);
- return new Color(Math.max((int)(color.getRed() *amount), 0),
- Math.max((int)(color.getGreen()*amount), 0),
- Math.max((int)(color.getBlue() *amount), 0),
+ return new Color(Math.max((int)(color.getRed() * amount), 0),
+ Math.max((int)(color.getGreen() * amount), 0),
+ Math.max((int)(color.getBlue() * amount), 0),
color.getAlpha()).getRGB();
}
diff --git a/src/main/java/dev/isxander/yacl/gui/CategoryListWidget.java b/src/client/java/dev/isxander/yacl/gui/CategoryListWidget.java
index 2cb6bb6..4dbcb11 100644
--- a/src/main/java/dev/isxander/yacl/gui/CategoryListWidget.java
+++ b/src/client/java/dev/isxander/yacl/gui/CategoryListWidget.java
@@ -11,11 +11,11 @@ import net.minecraft.client.util.math.MatrixStack;
import java.util.List;
-public class CategoryListWidget extends ElementListWidget<CategoryListWidget.CategoryEntry> {
+public class CategoryListWidget extends ElementListWidgetExt<CategoryListWidget.CategoryEntry> {
private final YACLScreen yaclScreen;
public CategoryListWidget(MinecraftClient client, YACLScreen yaclScreen, int screenWidth, int screenHeight) {
- super(client, screenWidth / 3, yaclScreen.searchFieldWidget.y - 5, 0, yaclScreen.searchFieldWidget.y - 5, 21);
+ super(client, 0, 0, screenWidth / 3, yaclScreen.searchFieldWidget.getY() - 5, true);
this.yaclScreen = yaclScreen;
setRenderBackground(false);
setRenderHorizontalShadows(false);
@@ -26,10 +26,10 @@ public class CategoryListWidget extends ElementListWidget<CategoryListWidget.Cat
}
@Override
- protected void renderList(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+ public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
double d = this.client.getWindow().getScaleFactor();
RenderSystem.enableScissor(0, (int)((yaclScreen.height - bottom) * d), (int)(width * d), (int)(height * d));
- super.renderList(matrices, mouseX, mouseY, delta);
+ super.render(matrices, mouseX, mouseY, delta);
RenderSystem.disableScissor();
}
@@ -54,6 +54,11 @@ public class CategoryListWidget extends ElementListWidget<CategoryListWidget.Cat
return width - 2;
}
+ @Override
+ protected void renderBackground(MatrixStack matrices) {
+
+ }
+
public class CategoryEntry extends Entry<CategoryEntry> {
private final CategoryWidget categoryButton;
public final int categoryIndex;
@@ -75,15 +80,20 @@ public class CategoryListWidget extends ElementListWidget<CategoryListWidget.Cat
mouseY = -20;
}
- categoryButton.y = y;
+ categoryButton.setY(y);
categoryButton.render(matrices, mouseX, mouseY, tickDelta);
}
- private void postRender(MatrixStack matrices, int mouseX, int mouseY, float tickDelta) {
+ public void postRender(MatrixStack matrices, int mouseX, int mouseY, float tickDelta) {
categoryButton.renderHoveredTooltip(matrices);
}
@Override
+ public int getItemHeight() {
+ return 21;
+ }
+
+ @Override
public List<? extends Element> children() {
return ImmutableList.of(categoryButton);
}
diff --git a/src/main/java/dev/isxander/yacl/gui/CategoryWidget.java b/src/client/java/dev/isxander/yacl/gui/CategoryWidget.java
index 3c5d8d2..3c5d8d2 100644
--- a/src/main/java/dev/isxander/yacl/gui/CategoryWidget.java
+++ b/src/client/java/dev/isxander/yacl/gui/CategoryWidget.java
diff --git a/src/client/java/dev/isxander/yacl/gui/ElementListWidgetExt.java b/src/client/java/dev/isxander/yacl/gui/ElementListWidgetExt.java
new file mode 100644
index 0000000..f2a19f2
--- /dev/null
+++ b/src/client/java/dev/isxander/yacl/gui/ElementListWidgetExt.java
@@ -0,0 +1,152 @@
+package dev.isxander.yacl.gui;
+
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.widget.ElementListWidget;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.util.math.MathHelper;
+import org.jetbrains.annotations.Nullable;
+
+public class ElementListWidgetExt<E extends ElementListWidgetExt.Entry<E>> extends ElementListWidget<E> {
+ protected final int x, y;
+
+ private double smoothScrollAmount = getScrollAmount();
+ private boolean returnSmoothAmount = false;
+ private final boolean doSmoothScrolling;
+
+ public ElementListWidgetExt(MinecraftClient client, int x, int y, int width, int height, boolean smoothScrolling) {
+ super(client, width, height, y, y + height, 22);
+ this.x = x;
+ this.y = y;
+ this.left = x;
+ this.right = this.left + width;
+ this.doSmoothScrolling = smoothScrolling;
+ }
+
+ @Override
+ public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
+ // default implementation bases scroll step from total height of entries, this is constant
+ this.setScrollAmount(this.getScrollAmount() - amount * 20);
+ return true;
+ }
+
+ @Override
+ protected void renderBackground(MatrixStack matrices) {
+ // render transparent background if in-game.
+ setRenderBackground(client.world == null);
+ if (client.world != null)
+ fill(matrices, left, top, right, bottom, 0x6B000000);
+ }
+
+ @Override
+ protected int getScrollbarPositionX() {
+ // default implementation does not respect left/right
+ return this.right - 2;
+ }
+
+ @Override
+ public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+ smoothScrollAmount = MathHelper.lerp(MinecraftClient.getInstance().getLastFrameDuration() * 0.5, smoothScrollAmount, getScrollAmount());
+ returnSmoothAmount = true;
+ super.render(matrices, mouseX, mouseY, delta);
+ returnSmoothAmount = false;
+ }
+
+ /**
+ * awful code to only use smooth scroll state when rendering,
+ * not other code that needs target scroll amount
+ */
+ @Override
+ public double getScrollAmount() {
+ if (returnSmoothAmount && doSmoothScrolling)
+ return smoothScrollAmount;
+
+ return super.getScrollAmount();
+ }
+
+ protected void resetSmoothScrolling() {
+ this.smoothScrollAmount = getScrollAmount();
+ }
+
+ public void postRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+ for (E entry : children()) {
+ entry.postRender(matrices, mouseX, mouseY, delta);
+ }
+ }
+
+ /*
+ below code is licensed from cloth-config under LGPL3
+ modified to inherit vanilla's EntryListWidget and use yarn mappings
+
+ code is responsible for having dynamic item heights
+ */
+
+ @Nullable
+ @Override
+ protected E getEntryAtPosition(double x, double y) {
+ int listMiddleX = this.left + this.width / 2;
+ int minX = listMiddleX - this.getRowWidth() / 2;
+ int maxX = listMiddleX + this.getRowWidth() / 2;
+ int currentY = MathHelper.floor(y - (double) this.top) - this.headerHeight + (int) this.getScrollAmount() - 4;
+ int itemY = 0;
+ int itemIndex = -1;
+ for (int i = 0; i < children().size(); i++) {
+ E item = children().get(i);
+ itemY += item.getItemHeight();
+ if (itemY > currentY) {
+ itemIndex = i;
+ break;
+ }
+ }
+ return x < (double) this.getScrollbarPositionX() && x >= minX && y <= maxX && itemIndex >= 0 && currentY >= 0 && itemIndex < this.getEntryCount() ? this.children().get(itemIndex) : null;
+ }
+
+ @Override
+ protected int getMaxPosition() {
+ return children().stream().map(E::getItemHeight).reduce(0, Integer::sum) + headerHeight;
+ }
+
+ @Override
+ protected void centerScrollOn(E entry) {
+ double d = (this.bottom - this.top) / -2d;
+ for (int i = 0; i < this.children().indexOf(entry) && i < this.getEntryCount(); i++)
+ d += children().get(i).getItemHeight();
+ this.setScrollAmount(d);
+ }
+
+ @Override
+ protected int getRowTop(int index) {
+ int integer = top + 4 - (int) this.getScrollAmount() + headerHeight;
+ for (int i = 0; i < children().size() && i < index; i++)
+ integer += children().get(i).getItemHeight();
+ return integer;
+ }
+
+ @Override
+ protected void renderList(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+ int left = this.getRowLeft();
+ int right = this.getRowWidth();
+ int count = this.getEntryCount();
+
+ for(int i = 0; i < count; ++i) {
+ E entry = children().get(i);
+ int top = this.getRowTop(i);
+ int bottom = top + entry.getItemHeight();
+ int entryHeight = entry.getItemHeight() - 4;
+ if (bottom >= this.top && top <= this.bottom) {
+ this.renderEntry(matrices, mouseX, mouseY, delta, i, left, top, right, entryHeight);
+ }
+ }
+ }
+
+ /* END cloth config code */
+
+ public abstract static class Entry<E extends ElementListWidgetExt.Entry<E>> extends ElementListWidget.Entry<E> {
+ public void postRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+
+ }
+
+ public int getItemHeight() {
+ return 22;
+ }
+ }
+}
diff --git a/src/main/java/dev/isxander/yacl/gui/LowProfileButtonWidget.java b/src/client/java/dev/isxander/yacl/gui/LowProfileButtonWidget.java
index 240cfb2..9fa01a7 100644
--- a/src/main/java/dev/isxander/yacl/gui/LowProfileButtonWidget.java
+++ b/src/client/java/dev/isxander/yacl/gui/LowProfileButtonWidget.java
@@ -1,6 +1,7 @@
package dev.isxander.yacl.gui;
import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.tooltip.Tooltip;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text;
@@ -8,18 +9,19 @@ import net.minecraft.util.math.MathHelper;
public class LowProfileButtonWidget extends ButtonWidget {
public LowProfileButtonWidget(int x, int y, int width, int height, Text message, PressAction onPress) {
- super(x, y, width, height, message, onPress);
+ super(x, y, width, height, message, onPress, DEFAULT_NARRATION_SUPPLIER);
}
- public LowProfileButtonWidget(int x, int y, int width, int height, Text message, PressAction onPress, TooltipSupplier tooltipSupplier) {
- super(x, y, width, height, message, onPress, tooltipSupplier);
+ public LowProfileButtonWidget(int x, int y, int width, int height, Text message, PressAction onPress, Tooltip tooltip) {
+ this(x, y, width, height, message, onPress);
+ setTooltip(tooltip);
}
@Override
public void renderButton(MatrixStack matrices, int mouseX, int mouseY, float delta) {
if (!isHovered()) {
int j = this.active ? 0xFFFFFF : 0xA0A0A0;
- drawCenteredText(matrices, MinecraftClient.getInstance().textRenderer, this.getMessage(), this.x + this.width / 2, this.y + (this.height - 8) / 2, j | MathHelper.ceil(this.alpha * 255.0F) << 24);
+ drawCenteredText(matrices, MinecraftClient.getInstance().textRenderer, this.getMessage(), this.getX() + this.width / 2, this.getY() + (this.height - 8) / 2, j | MathHelper.ceil(this.alpha * 255.0F) << 24);
} else {
super.renderButton(matrices, mouseX, mouseY, delta);
}
diff --git a/src/main/java/dev/isxander/yacl/gui/OptionListWidget.java b/src/client/java/dev/isxander/yacl/gui/OptionListWidget.java
index cf50a58..7ea275b 100644
--- a/src/main/java/dev/isxander/yacl/gui/OptionListWidget.java
+++ b/src/client/java/dev/isxander/yacl/gui/OptionListWidget.java
@@ -22,20 +22,15 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.function.Supplier;
-public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry> {
+public class OptionListWidget extends ElementListWidgetExt<OptionListWidget.Entry> {
private final YACLScreen yaclScreen;
private boolean singleCategory = false;
private ImmutableList<Entry> viewableChildren;
- private double smoothScrollAmount = getScrollAmount();
- private boolean returnSmoothAmount = false;
-
public OptionListWidget(YACLScreen screen, MinecraftClient client, int width, int height) {
- super(client, width / 3 * 2, height, 0, height, 22);
+ super(client, width / 3, 0, width / 3 * 2, height, true);
this.yaclScreen = screen;
- left = width - this.width;
- right = width;
refreshOptions();
}
@@ -78,6 +73,7 @@ public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry>
recacheViewableChildren();
setScrollAmount(0);
+ resetSmoothScrolling();
}
public void expandAllGroups() {
@@ -88,97 +84,6 @@ public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry>
}
}
- /*
- below code is licensed from cloth-config under LGPL3
- modified to inherit vanilla's EntryListWidget and use yarn mappings
- */
-
- @Nullable
- @Override
- protected Entry getEntryAtPosition(double x, double y) {
- int listMiddleX = this.left + this.width / 2;
- int minX = listMiddleX - this.getRowWidth() / 2;
- int maxX = listMiddleX + this.getRowWidth() / 2;
- int currentY = MathHelper.floor(y - (double) this.top) - this.headerHeight + (int) this.getScrollAmount() - 4;
- int itemY = 0;
- int itemIndex = -1;
- for (int i = 0; i < children().size(); i++) {
- Entry item = children().get(i);
- itemY += item.getItemHeight();
- if (itemY > currentY) {
- itemIndex = i;
- break;
- }
- }
- return x < (double) this.getScrollbarPositionX() && x >= minX && y <= maxX && itemIndex >= 0 && currentY >= 0 && itemIndex < this.getEntryCount() ? this.children().get(itemIndex) : null;
- }
-
- @Override
- protected int getMaxPosition() {
- return children().stream().map(Entry::getItemHeight).reduce(0, Integer::sum) + headerHeight;
- }
-
- @Override
- protected void centerScrollOn(Entry entry) {
- double d = (this.bottom - this.top) / -2d;
- for (int i = 0; i < this.children().indexOf(entry) && i < this.getEntryCount(); i++)
- d += children().get(i).getItemHeight();
- this.setScrollAmount(d);
- }
-
- @Override
- protected int getRowTop(int index) {
- int integer = top + 4 - (int) this.getScrollAmount() + headerHeight;
- for (int i = 0; i < children().size() && i < index; i++)
- integer += children().get(i).getItemHeight();
- return integer;
- }
-
- @Override
- protected void renderList(MatrixStack matrices, int mouseX, int mouseY, float delta) {
- int left = this.getRowLeft();
- int right = this.getRowWidth();
- int count = this.getEntryCount();
-
- for(int i = 0; i < count; ++i) {
- Entry entry = children().get(i);
- int top = this.getRowTop(i);
- int bottom = top + entry.getItemHeight();
- int entryHeight = entry.getItemHeight() - 4;
- if (bottom >= this.top && top <= this.bottom) {
- this.renderEntry(matrices, mouseX, mouseY, delta, i, left, top, right, entryHeight);
- }
- }
- }
-
- /* END cloth config code */
-
- @Override
- public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
- smoothScrollAmount = MathHelper.lerp(MinecraftClient.getInstance().getLastFrameDuration() * 0.5, smoothScrollAmount, getScrollAmount());
- returnSmoothAmount = true;
- super.render(matrices, mouseX, mouseY, delta);
- returnSmoothAmount = false;
- }
-
- /**
- * awful code to only use smooth scroll state when rendering,
- * not other code that needs target scroll amount
- */
- @Override
- public double getScrollAmount() {
- if (returnSmoothAmount)
- return smoothScrollAmount;
-
- return super.getScrollAmount();
- }
-
- public void postRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {
- for (Entry entry : children()) {
- entry.postRender(matrices, mouseX, mouseY, delta);
- }
- }
-
@Override
public int getRowWidth() {
return Math.min(396, (int)(width / 1.3f));
@@ -196,12 +101,13 @@ public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry>
@Override
public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
+ super.mouseScrolled(mouseX, mouseY, amount);
+
for (Entry child : children()) {
if (child.mouseScrolled(mouseX, mouseY, amount))
- return true;
+ break;
}
- this.setScrollAmount(this.getScrollAmount() - amount * 20 /* * (double) (getMaxScroll() / getEntryCount()) / 2.0D */);
return true;
}
@@ -227,14 +133,7 @@ public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry>
@Override
protected int getScrollbarPositionX() {
- return left + width - (int)(width * 0.05f);
- }
-
- @Override
- protected void renderBackground(MatrixStack matrices) {
- setRenderBackground(client.world == null);
- if (client.world != null)
- fill(matrices, left, top, right, bottom, 0x6B000000);
+ return right - (int)(width * 0.05f);
}
public void recacheViewableChildren() {
@@ -254,19 +153,11 @@ public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry>
return viewableChildren;
}
- public abstract class Entry extends ElementListWidget.Entry<Entry> {
- public void postRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {
-
- }
-
+ public abstract class Entry extends ElementListWidgetExt.Entry<Entry> {
public boolean isViewable() {
return true;
}
- public int getItemHeight() {
- return 22;
- }
-
protected boolean isHovered() {
return Objects.equals(getHoveredEntry(), this);
}
@@ -312,7 +203,7 @@ public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry>
widget.render(matrices, mouseX, mouseY, tickDelta);
if (resetButton != null) {
- resetButton.y = y;
+ resetButton.setY(y);
resetButton.render(matrices, mouseX, mouseY, tickDelta);
}
}
@@ -402,8 +293,8 @@ public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry>
public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {
this.y = y;
- expandMinimizeButton.x = x;
- expandMinimizeButton.y = y + entryHeight / 2 - expandMinimizeButton.getHeight() / 2;
+ expandMinimizeButton.setX(x);
+ expandMinimizeButton.setY(y + entryHeight / 2 - expandMinimizeButton.getHeight() / 2);
expandMinimizeButton.render(matrices, mouseX, mouseY, tickDelta);
wrappedName.drawCenterWithShadow(matrices, x + entryWidth / 2, y + getYPadding());
@@ -426,7 +317,7 @@ public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry>
}
private void updateExpandMinimizeText() {
- expandMinimizeButton.setMessage(Text.of(isExpanded() ? "\u25BC" : "\u25B6"));
+ expandMinimizeButton.setMessage(Text.of(isExpanded() ? "â–¼" : "â–¶"));
}
public void setOptionEntries(List<OptionEntry> optionEntries) {
diff --git a/src/main/java/dev/isxander/yacl/gui/RequireRestartScreen.java b/src/client/java/dev/isxander/yacl/gui/RequireRestartScreen.java
index 3c46738..3c46738 100644
--- a/src/main/java/dev/isxander/yacl/gui/RequireRestartScreen.java
+++ b/src/client/java/dev/isxander/yacl/gui/RequireRestartScreen.java
diff --git a/src/main/java/dev/isxander/yacl/gui/SearchFieldWidget.java b/src/client/java/dev/isxander/yacl/gui/SearchFieldWidget.java
index 6184405..5b7c9dc 100644
--- a/src/main/java/dev/isxander/yacl/gui/SearchFieldWidget.java
+++ b/src/client/java/dev/isxander/yacl/gui/SearchFieldWidget.java
@@ -25,7 +25,7 @@ public class SearchFieldWidget extends TextFieldWidget {
public void renderButton(MatrixStack matrices, int mouseX, int mouseY, float delta) {
super.renderButton(matrices, mouseX, mouseY, delta);
if (isVisible() && isEmpty()) {
- textRenderer.drawWithShadow(matrices, emptyText, x + 4, this.y + (this.height - 8) / 2f, 0x707070);
+ textRenderer.drawWithShadow(matrices, emptyText, getX() + 4, this.getY() + (this.height - 8) / 2f, 0x707070);
}
}
diff --git a/src/main/java/dev/isxander/yacl/gui/TextScaledButtonWidget.java b/src/client/java/dev/isxander/yacl/gui/TextScaledButtonWidget.java
index d588d52..2d0a99c 100644
--- a/src/main/java/dev/isxander/yacl/gui/TextScaledButtonWidget.java
+++ b/src/client/java/dev/isxander/yacl/gui/TextScaledButtonWidget.java
@@ -2,6 +2,7 @@ package dev.isxander.yacl.gui;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
+import net.minecraft.client.gui.tooltip.Tooltip;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.OrderedText;
@@ -12,13 +13,13 @@ public class TextScaledButtonWidget extends ButtonWidget {
public float textScale;
public TextScaledButtonWidget(int x, int y, int width, int height, float textScale, Text message, PressAction onPress) {
- super(x, y, width, height, message, onPress);
+ super(x, y, width, height, message, onPress, DEFAULT_NARRATION_SUPPLIER);
this.textScale = textScale;
}
- public TextScaledButtonWidget(int x, int y, int width, int height, float textScale, Text message, PressAction onPress, TooltipSupplier tooltipSupplier) {
- super(x, y, width, height, message, onPress, tooltipSupplier);
- this.textScale = textScale;
+ public TextScaledButtonWidget(int x, int y, int width, int height, float textScale, Text message, PressAction onPress, Tooltip tooltip) {
+ this(x, y, width, height, textScale, message, onPress);
+ setTooltip(tooltip);
}
@Override
@@ -35,7 +36,7 @@ public class TextScaledButtonWidget extends ButtonWidget {
TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer;
matrices.push();
- matrices.translate(((this.x + this.width / 2f) - textRenderer.getWidth(orderedText) * textScale / 2), (float)this.y + (this.height - 8 * textScale) / 2f / textScale, 0);
+ matrices.translate(((this.getX() + this.width / 2f) - textRenderer.getWidth(orderedText) * textScale / 2), (float)this.getY() + (this.height - 8 * textScale) / 2f / textScale, 0);
matrices.scale(textScale, textScale, 1);
textRenderer.drawWithShadow(matrices, orderedText, 0, 0, j | MathHelper.ceil(this.alpha * 255.0F) << 24);
matrices.pop();
diff --git a/src/main/java/dev/isxander/yacl/gui/TooltipButtonWidget.java b/src/client/java/dev/isxander/yacl/gui/TooltipButtonWidget.java
index d105f7b..b034f4b 100644
--- a/src/main/java/dev/isxander/yacl/gui/TooltipButtonWidget.java
+++ b/src/client/java/dev/isxander/yacl/gui/TooltipButtonWidget.java
@@ -13,14 +13,14 @@ public class TooltipButtonWidget extends ButtonWidget {
protected MultilineText wrappedDescription;
public TooltipButtonWidget(Screen screen, int x, int y, int width, int height, Text message, Text tooltip, PressAction onPress) {
- super(x, y, width, height, message, onPress);
+ super(x, y, width, height, message, onPress, DEFAULT_NARRATION_SUPPLIER);
this.screen = screen;
setTooltip(tooltip);
}
public void renderHoveredTooltip(MatrixStack matrices) {
if (isHovered()) {
- YACLScreen.renderMultilineTooltip(matrices, MinecraftClient.getInstance().textRenderer, wrappedDescription, x + width / 2, y - 4, y + height + 4, screen.width, screen.height);
+ YACLScreen.renderMultilineTooltip(matrices, MinecraftClient.getInstance().textRenderer, wrappedDescription, getX() + width / 2, getY() - 4, getY() + height + 4, screen.width, screen.height);
}
}
diff --git a/src/main/java/dev/isxander/yacl/gui/YACLScreen.java b/src/client/java/dev/isxander/yacl/gui/YACLScreen.java
index 629fd4c..1fbc769 100644
--- a/src/main/java/dev/isxander/yacl/gui/YACLScreen.java
+++ b/src/client/java/dev/isxander/yacl/gui/YACLScreen.java
@@ -7,14 +7,16 @@ import dev.isxander.yacl.api.utils.MutableDimension;
import dev.isxander.yacl.api.utils.OptionUtils;
import net.minecraft.client.font.MultilineText;
import net.minecraft.client.font.TextRenderer;
+import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.tooltip.TooltipBackgroundRenderer;
import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
-import net.minecraft.util.math.MathHelper;
-import net.minecraft.util.math.Matrix4f;
+import org.joml.Matrix4f;
import java.util.HashSet;
import java.util.Set;
@@ -72,10 +74,10 @@ public class YACLScreen extends Screen {
});
actionDim.expand(-actionDim.width() / 2 - 2, 0).move(-actionDim.width() / 2 - 2, -22);
cancelResetButton = new TooltipButtonWidget(this, actionDim.x() - actionDim.width() / 2, actionDim.y(), actionDim.width(), actionDim.height(), Text.empty(), Text.empty(), (btn) -> {
- if (pendingChanges()) {
+ if (pendingChanges()) { // if pending changes, button acts as a cancel button
OptionUtils.forEachOptions(config, Option::forgetPendingValue);
close();
- } else {
+ } else { // if not, button acts as a reset button
OptionUtils.forEachOptions(config, Option::requestSetDefault);
}
@@ -85,7 +87,7 @@ public class YACLScreen extends Screen {
OptionUtils.forEachOptions(config, Option::forgetPendingValue);
});
- searchFieldWidget = new SearchFieldWidget(this, textRenderer, width / 3 / 2 - paddedWidth / 2 + 1, undoButton.y - 22, paddedWidth - 2, 18, Text.translatable("gui.recipebook.search_hint"), Text.translatable("gui.recipebook.search_hint"));
+ searchFieldWidget = new SearchFieldWidget(this, textRenderer, width / 3 / 2 - paddedWidth / 2 + 1, undoButton.getY() - 22, paddedWidth - 2, 18, Text.translatable("gui.recipebook.search_hint"), Text.translatable("gui.recipebook.search_hint"));
categoryList = new CategoryListWidget(client, this, width, height);
addSelectableChild(categoryList);
@@ -159,9 +161,9 @@ public class YACLScreen extends Screen {
boolean pendingChanges = pendingChanges();
undoButton.active = pendingChanges;
- finishedSaveButton.setMessage(pendingChanges ? Text.translatable("yacl.gui.save") : Text.translatable("gui.done"));
+ finishedSaveButton.setMessage(pendingChanges ? Text.translatable("yacl.gui.save") : ScreenTexts.DONE);
finishedSaveButton.setTooltip(pendingChanges ? Text.translatable("yacl.gui.save.tooltip") : Text.translatable("yacl.gui.finished.tooltip"));
- cancelResetButton.setMessage(pendingChanges ? Text.translatable("gui.cancel") : Text.translatable("controls.reset"));
+ cancelResetButton.setMessage(pendingChanges ? ScreenTexts.CANCEL : Text.translatable("controls.reset"));
cancelResetButton.setTooltip(pendingChanges ? Text.translatable("yacl.gui.cancel.tooltip") : Text.translatable("yacl.gui.reset.tooltip"));
}
@@ -241,23 +243,24 @@ public class YACLScreen extends Screen {
matrices.push();
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuffer();
- RenderSystem.setShader(GameRenderer::getPositionColorShader);
+ RenderSystem.setShader(GameRenderer::getPositionColorProgram);
bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
Matrix4f matrix4f = matrices.peek().getPositionMatrix();
- fillGradient(matrix4f, bufferBuilder, drawX - 3, drawY - 4, drawX + maxWidth + 3, drawY - 3, 400, -267386864, -267386864);
- fillGradient(matrix4f, bufferBuilder, drawX - 3, drawY + height + 3, drawX + maxWidth + 3, drawY + height + 4, 400, -267386864, -267386864);
- fillGradient(matrix4f, bufferBuilder, drawX - 3, drawY - 3, drawX + maxWidth + 3, drawY + height + 3, 400, -267386864, -267386864);
- fillGradient(matrix4f, bufferBuilder, drawX - 4, drawY - 3, drawX - 3, drawY + height + 3, 400, -267386864, -267386864);
- fillGradient(matrix4f, bufferBuilder, drawX + maxWidth + 3, drawY - 3, drawX + maxWidth + 4, drawY + height + 3, 400, -267386864, -267386864);
- fillGradient(matrix4f, bufferBuilder, drawX - 3, drawY - 3 + 1, drawX - 3 + 1, drawY + height + 3 - 1, 400, 1347420415, 1344798847);
- fillGradient(matrix4f, bufferBuilder, drawX + maxWidth + 2, drawY - 3 + 1, drawX + maxWidth + 3, drawY + height + 3 - 1, 400, 1347420415, 1344798847);
- fillGradient(matrix4f, bufferBuilder, drawX - 3, drawY - 3, drawX + maxWidth + 3, drawY - 3 + 1, 400, 1347420415, 1347420415);
- fillGradient(matrix4f, bufferBuilder, drawX - 3, drawY + height + 2, drawX + maxWidth + 3, drawY + height + 3, 400, 1344798847, 1344798847);
+ TooltipBackgroundRenderer.render(
+ DrawableHelper::fillGradient,
+ matrix4f,
+ bufferBuilder,
+ drawX,
+ drawY,
+ maxWidth,
+ height,
+ 400
+ );
RenderSystem.enableDepthTest();
RenderSystem.disableTexture();
RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();
- BufferRenderer.drawWithShader(bufferBuilder.end());
+ BufferRenderer.drawWithGlobalProgram(bufferBuilder.end());
RenderSystem.disableBlend();
RenderSystem.enableTexture();
matrices.translate(0.0, 0.0, 400.0);
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/ActionController.java b/src/client/java/dev/isxander/yacl/gui/controllers/ActionController.java
index b8e2cd1..7666dff 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/ActionController.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/ActionController.java
@@ -5,8 +5,8 @@ import dev.isxander.yacl.api.Controller;
import dev.isxander.yacl.api.utils.Dimension;
import dev.isxander.yacl.gui.AbstractWidget;
import dev.isxander.yacl.gui.YACLScreen;
+import net.minecraft.client.util.InputUtil;
import net.minecraft.text.Text;
-import org.lwjgl.glfw.GLFW;
import java.util.function.BiConsumer;
@@ -94,7 +94,7 @@ public class ActionController implements Controller<BiConsumer<YACLScreen, Butto
return false;
}
- if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_SPACE || keyCode == GLFW.GLFW_KEY_KP_ENTER) {
+ if (keyCode == InputUtil.GLFW_KEY_ENTER || keyCode == InputUtil.GLFW_KEY_SPACE || keyCode == InputUtil.GLFW_KEY_KP_ENTER) {
executeAction();
return true;
}
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/BooleanController.java b/src/client/java/dev/isxander/yacl/gui/controllers/BooleanController.java
index b7a77dd..3a8e5c3 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/BooleanController.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/BooleanController.java
@@ -5,7 +5,9 @@ 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.util.InputUtil;
import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import org.lwjgl.glfw.GLFW;
@@ -19,8 +21,8 @@ public class BooleanController implements Controller<Boolean> {
public static final Function<Boolean, Text> ON_OFF_FORMATTER = (state) ->
state
- ? Text.translatable("options.on")
- : Text.translatable("options.off");
+ ? ScreenTexts.ON
+ : ScreenTexts.OFF;
public static final Function<Boolean, Text> TRUE_FALSE_FORMATTER = (state) ->
state
@@ -29,8 +31,8 @@ public class BooleanController implements Controller<Boolean> {
public static final Function<Boolean, Text> YES_NO_FORMATTER = (state) ->
state
- ? Text.translatable("gui.yes")
- : Text.translatable("gui.no");
+ ? ScreenTexts.YES
+ : ScreenTexts.NO;
private final Option<Boolean> option;
private final Function<Boolean, Text> valueFormatter;
@@ -102,7 +104,7 @@ public class BooleanController implements Controller<Boolean> {
}
public static class BooleanControllerElement extends ControllerWidget<BooleanController> {
- private BooleanControllerElement(BooleanController control, YACLScreen screen, Dimension<Integer> dim) {
+ public BooleanControllerElement(BooleanController control, YACLScreen screen, Dimension<Integer> dim) {
super(control, screen, dim);
}
@@ -145,7 +147,7 @@ public class BooleanController implements Controller<Boolean> {
return false;
}
- if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_SPACE || keyCode == GLFW.GLFW_KEY_KP_ENTER) {
+ if (keyCode == InputUtil.GLFW_KEY_ENTER || keyCode == InputUtil.GLFW_KEY_SPACE || keyCode == InputUtil.GLFW_KEY_KP_ENTER) {
toggleSetting();
return true;
}
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/ColorController.java b/src/client/java/dev/isxander/yacl/gui/controllers/ColorController.java
index 0a83fbe..b8e1942 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/ColorController.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/ColorController.java
@@ -14,7 +14,7 @@ import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
-import java.awt.*;
+import java.awt.Color;
import java.util.List;
/**
@@ -108,7 +108,7 @@ public class ColorController implements IStringController<Color> {
private final List<Character> allowedChars;
public ColorControllerElement(ColorController control, YACLScreen screen, Dimension<Integer> dim) {
- super(control, screen, dim);
+ super(control, screen, dim, true);
this.colorController = control;
this.allowedChars = ImmutableList.of('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
}
@@ -135,21 +135,22 @@ public class ColorController implements IStringController<Color> {
if (caretPos == 0)
return;
- string = string.substring(0, Math.min(inputField.length() - caretPos, string.length()));
+ String trimmed = string.substring(0, Math.min(inputField.length() - caretPos, string.length()));
- inputField.replace(caretPos, caretPos + string.length(), string);
- caretPos += string.length();
- setSelectionLength();
-
- updateControl();
+ if (modifyInput(builder -> builder.replace(caretPos, caretPos + trimmed.length(), trimmed))) {
+ caretPos += trimmed.length();
+ setSelectionLength();
+ updateControl();
+ }
}
@Override
protected void doBackspace() {
if (caretPos > 1) {
- inputField.setCharAt(caretPos - 1, '0');
- caretPos--;
- updateControl();
+ if (modifyInput(builder -> builder.setCharAt(caretPos - 1, '0'))) {
+ caretPos--;
+ updateControl();
+ }
}
}
@@ -182,11 +183,13 @@ public class ColorController implements IStringController<Color> {
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
+ int prevSelectionLength = selectionLength;
+ selectionLength = 0;
if (super.keyPressed(keyCode, scanCode, modifiers)) {
caretPos = Math.max(1, caretPos);
setSelectionLength();
return true;
- }
+ } else selectionLength = prevSelectionLength;
return false;
}
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java b/src/client/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java
index c7f9e97..cebaba7 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java
@@ -4,6 +4,7 @@ import dev.isxander.yacl.api.Controller;
import dev.isxander.yacl.api.utils.Dimension;
import dev.isxander.yacl.gui.AbstractWidget;
import dev.isxander.yacl.gui.YACLScreen;
+import dev.isxander.yacl.impl.utils.YACLConstants;
import net.minecraft.client.font.MultilineText;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
@@ -44,6 +45,9 @@ public abstract class ControllerWidget<T extends Controller<?>> extends Abstract
nameString = nameString.substring(0, Math.max(nameString.length() - (firstIter ? 2 : 5), 0)).trim();
nameString += "...";
+ if (nameString.equals("..."))
+ break;
+
firstIter = false;
}
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/LabelController.java b/src/client/java/dev/isxander/yacl/gui/controllers/LabelController.java
index 8369680..8369680 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/LabelController.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/LabelController.java
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/TickBoxController.java b/src/client/java/dev/isxander/yacl/gui/controllers/TickBoxController.java
index ff693a9..b0ae449 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/TickBoxController.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/TickBoxController.java
@@ -6,9 +6,9 @@ import dev.isxander.yacl.api.utils.Dimension;
import dev.isxander.yacl.gui.AbstractWidget;
import dev.isxander.yacl.gui.YACLScreen;
import net.minecraft.client.gui.DrawableHelper;
+import net.minecraft.client.util.InputUtil;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text;
-import org.lwjgl.glfw.GLFW;
/**
* This controller renders a tickbox
@@ -50,7 +50,7 @@ public class TickBoxController implements Controller<Boolean> {
}
public static class TickBoxControllerElement extends ControllerWidget<TickBoxController> {
- private TickBoxControllerElement(TickBoxController control, YACLScreen screen, Dimension<Integer> dim) {
+ public TickBoxControllerElement(TickBoxController control, YACLScreen screen, Dimension<Integer> dim) {
super(control, screen, dim);
}
@@ -93,6 +93,11 @@ public class TickBoxController implements Controller<Boolean> {
return 10;
}
+ @Override
+ protected int getUnhoveredControlWidth() {
+ return 10;
+ }
+
public void toggleSetting() {
control.option().requestSet(!control.option().pendingValue());
playDownSound();
@@ -104,7 +109,7 @@ public class TickBoxController implements Controller<Boolean> {
return false;
}
- if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_SPACE || keyCode == GLFW.GLFW_KEY_KP_ENTER) {
+ if (keyCode == InputUtil.GLFW_KEY_ENTER || keyCode == InputUtil.GLFW_KEY_SPACE || keyCode == InputUtil.GLFW_KEY_KP_ENTER) {
toggleSetting();
return true;
}
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/cycling/CyclingControllerElement.java b/src/client/java/dev/isxander/yacl/gui/controllers/cycling/CyclingControllerElement.java
index ab0a9c3..246fbec 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/cycling/CyclingControllerElement.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/cycling/CyclingControllerElement.java
@@ -4,7 +4,7 @@ import dev.isxander.yacl.api.utils.Dimension;
import dev.isxander.yacl.gui.YACLScreen;
import dev.isxander.yacl.gui.controllers.ControllerWidget;
import net.minecraft.client.gui.screen.Screen;
-import org.lwjgl.glfw.GLFW;
+import net.minecraft.client.util.InputUtil;
public class CyclingControllerElement extends ControllerWidget<ICyclingController<?>> {
@@ -39,11 +39,11 @@ public class CyclingControllerElement extends ControllerWidget<ICyclingControlle
return false;
switch (keyCode) {
- case GLFW.GLFW_KEY_LEFT, GLFW.GLFW_KEY_DOWN ->
+ case InputUtil.GLFW_KEY_LEFT, InputUtil.GLFW_KEY_DOWN ->
cycleValue(-1);
- case GLFW.GLFW_KEY_RIGHT, GLFW.GLFW_KEY_UP ->
+ case InputUtil.GLFW_KEY_RIGHT, InputUtil.GLFW_KEY_UP ->
cycleValue(1);
- case GLFW.GLFW_KEY_ENTER, GLFW.GLFW_KEY_SPACE, GLFW.GLFW_KEY_KP_ENTER ->
+ case InputUtil.GLFW_KEY_ENTER, InputUtil.GLFW_KEY_SPACE, InputUtil.GLFW_KEY_KP_ENTER ->
cycleValue(Screen.hasControlDown() || Screen.hasShiftDown() ? -1 : 1);
default -> {
return false;
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/cycling/CyclingListController.java b/src/client/java/dev/isxander/yacl/gui/controllers/cycling/CyclingListController.java
index 3b14066..3b14066 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/cycling/CyclingListController.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/cycling/CyclingListController.java
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/cycling/EnumController.java b/src/client/java/dev/isxander/yacl/gui/controllers/cycling/EnumController.java
index bc9f46d..bc9f46d 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/cycling/EnumController.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/cycling/EnumController.java
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/cycling/ICyclingController.java b/src/client/java/dev/isxander/yacl/gui/controllers/cycling/ICyclingController.java
index 081b572..081b572 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/cycling/ICyclingController.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/cycling/ICyclingController.java
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/package-info.java b/src/client/java/dev/isxander/yacl/gui/controllers/package-info.java
index 12ce86b..12ce86b 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/package-info.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/package-info.java
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/slider/DoubleSliderController.java b/src/client/java/dev/isxander/yacl/gui/controllers/slider/DoubleSliderController.java
index b530e8c..54c7476 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/slider/DoubleSliderController.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/slider/DoubleSliderController.java
@@ -13,7 +13,7 @@ public class DoubleSliderController implements ISliderController<Double> {
/**
* Formats doubles to two decimal places
*/
- public static final Function<Double, Text> DEFAULT_FORMATTER = value -> Text.of(String.format("%,.2f", value));
+ public static final Function<Double, Text> DEFAULT_FORMATTER = value -> Text.of(String.format("%,.2f", value).replaceAll("[\u00a0\u202F]", " "));
private final Option<Double> option;
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/slider/FloatSliderController.java b/src/client/java/dev/isxander/yacl/gui/controllers/slider/FloatSliderController.java
index d7c203e..84ca9a2 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/slider/FloatSliderController.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/slider/FloatSliderController.java
@@ -13,7 +13,7 @@ public class FloatSliderController implements ISliderController<Float> {
/**
* Formats floats to one decimal place
*/
- public static final Function<Float, Text> DEFAULT_FORMATTER = value -> Text.of(String.format("%,.1f", value));
+ public static final Function<Float, Text> DEFAULT_FORMATTER = value -> Text.of(String.format("%,.1f", value).replaceAll("[\u00a0\u202F]", " "));
private final Option<Float> option;
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/slider/ISliderController.java b/src/client/java/dev/isxander/yacl/gui/controllers/slider/ISliderController.java
index aa3c18f..aa3c18f 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/slider/ISliderController.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/slider/ISliderController.java
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/slider/IntegerSliderController.java b/src/client/java/dev/isxander/yacl/gui/controllers/slider/IntegerSliderController.java
index a8bca7c..50ec9d2 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/slider/IntegerSliderController.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/slider/IntegerSliderController.java
@@ -10,7 +10,7 @@ import java.util.function.Function;
* {@link ISliderController} for integers.
*/
public class IntegerSliderController implements ISliderController<Integer> {
- public static final Function<Integer, Text> DEFAULT_FORMATTER = value -> Text.of(String.format("%,d", value));
+ public static final Function<Integer, Text> DEFAULT_FORMATTER = value -> Text.of(String.format("%,d", value).replaceAll("[\u00a0\u202F]", " "));
private final Option<Integer> option;
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/slider/LongSliderController.java b/src/client/java/dev/isxander/yacl/gui/controllers/slider/LongSliderController.java
index 50559d5..3038402 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/slider/LongSliderController.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/slider/LongSliderController.java
@@ -10,7 +10,7 @@ import java.util.function.Function;
* {@link ISliderController} for longs.
*/
public class LongSliderController implements ISliderController<Long> {
- public static final Function<Long, Text> DEFAULT_FORMATTER = value -> Text.of(String.format("%,d", value));
+ public static final Function<Long, Text> DEFAULT_FORMATTER = value -> Text.of(String.format("%,d", value).replaceAll("[\u00a0\u202F]", " "));
private final Option<Long> option;
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/slider/SliderControllerElement.java b/src/client/java/dev/isxander/yacl/gui/controllers/slider/SliderControllerElement.java
index 913cc00..c78e0eb 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/slider/SliderControllerElement.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/slider/SliderControllerElement.java
@@ -5,9 +5,9 @@ import dev.isxander.yacl.gui.YACLScreen;
import dev.isxander.yacl.gui.controllers.ControllerWidget;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.util.InputUtil;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.MathHelper;
-import org.lwjgl.glfw.GLFW;
public class SliderControllerElement extends ControllerWidget<ISliderController<?>> {
private final double min, max, interval;
@@ -104,8 +104,8 @@ public class SliderControllerElement extends ControllerWidget<ISliderController<
return false;
switch (keyCode) {
- case GLFW.GLFW_KEY_LEFT, GLFW.GLFW_KEY_DOWN -> incrementValue(-1);
- case GLFW.GLFW_KEY_RIGHT, GLFW.GLFW_KEY_UP -> incrementValue(1);
+ case InputUtil.GLFW_KEY_LEFT, InputUtil.GLFW_KEY_DOWN -> incrementValue(-1);
+ case InputUtil.GLFW_KEY_RIGHT, InputUtil.GLFW_KEY_UP -> incrementValue(1);
default -> {
return false;
}
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/slider/package-info.java b/src/client/java/dev/isxander/yacl/gui/controllers/slider/package-info.java
index bff0d57..bff0d57 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/slider/package-info.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/slider/package-info.java
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/string/IStringController.java b/src/client/java/dev/isxander/yacl/gui/controllers/string/IStringController.java
index 41843b8..553e278 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/string/IStringController.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/string/IStringController.java
@@ -2,6 +2,9 @@ package dev.isxander.yacl.gui.controllers.string;
import dev.isxander.yacl.api.Controller;
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.text.Text;
/**
@@ -29,4 +32,13 @@ public interface IStringController<T> extends Controller<T> {
default Text formatValue() {
return Text.of(getString());
}
+
+ default boolean isInputValid(String input) {
+ return true;
+ }
+
+ @Override
+ default AbstractWidget provideWidget(YACLScreen screen, Dimension<Integer> widgetDimension) {
+ return new StringControllerElement(this, screen, widgetDimension, true);
+ }
}
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/string/StringController.java b/src/client/java/dev/isxander/yacl/gui/controllers/string/StringController.java
index 0caaa93..3a07641 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/string/StringController.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/string/StringController.java
@@ -37,9 +37,4 @@ public class StringController implements IStringController<String> {
public void setFromString(String value) {
option().requestSet(value);
}
-
- @Override
- public AbstractWidget provideWidget(YACLScreen screen, Dimension<Integer> widgetDimension) {
- return new StringControllerElement(this, screen, widgetDimension);
- }
}
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/string/StringControllerElement.java b/src/client/java/dev/isxander/yacl/gui/controllers/string/StringControllerElement.java
index 0c3b7c9..47a4c96 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/string/StringControllerElement.java
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/string/StringControllerElement.java
@@ -5,13 +5,17 @@ import dev.isxander.yacl.gui.YACLScreen;
import dev.isxander.yacl.gui.controllers.ControllerWidget;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.util.InputUtil;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
-import org.lwjgl.glfw.GLFW;
+
+import java.util.function.Consumer;
public class StringControllerElement extends ControllerWidget<IStringController<?>> {
- protected StringBuilder inputField;
+ protected final boolean instantApply;
+
+ protected String inputField;
protected Dimension<Integer> inputFieldBounds;
protected boolean inputFieldFocused;
@@ -22,12 +26,14 @@ public class StringControllerElement extends ControllerWidget<IStringController<
private final Text emptyText;
- public StringControllerElement(IStringController<?> control, YACLScreen screen, Dimension<Integer> dim) {
+ public StringControllerElement(IStringController<?> control, YACLScreen screen, Dimension<Integer> dim, boolean instantApply) {
super(control, screen, dim);
- inputField = new StringBuilder(control.getString());
+ this.instantApply = instantApply;
+ inputField = control.getString();
inputFieldFocused = false;
selectionLength = 0;
emptyText = Text.literal("Click to type...").formatted(Formatting.GRAY);
+ control.option().addListener((opt, val) -> inputField = control.getString());
setDimension(dim);
}
@@ -35,12 +41,14 @@ public class StringControllerElement extends ControllerWidget<IStringController<
protected void drawHoveredControl(MatrixStack matrices, int mouseX, int mouseY, float delta) {
ticks += delta;
+ String text = getValueText().getString();
+
DrawableHelper.fill(matrices, inputFieldBounds.x(), inputFieldBounds.yLimit(), inputFieldBounds.xLimit(), inputFieldBounds.yLimit() + 1, -1);
DrawableHelper.fill(matrices, inputFieldBounds.x() + 1, inputFieldBounds.yLimit() + 1, inputFieldBounds.xLimit() + 1, inputFieldBounds.yLimit() + 2, 0xFF404040);
if (inputFieldFocused || focused) {
- int caretX = inputFieldBounds.x() + textRenderer.getWidth(control.getString().substring(0, caretPos)) - 1;
- if (inputField.isEmpty())
+ int caretX = inputFieldBounds.x() + textRenderer.getWidth(text.substring(0, caretPos)) - 1;
+ if (text.isEmpty())
caretX += inputFieldBounds.width() / 2;
if (ticks % 20 <= 10) {
@@ -48,7 +56,7 @@ public class StringControllerElement extends ControllerWidget<IStringController<
}
if (selectionLength != 0) {
- int selectionX = inputFieldBounds.x() + textRenderer.getWidth(control.getString().substring(0, caretPos + selectionLength));
+ int selectionX = inputFieldBounds.x() + textRenderer.getWidth(text.substring(0, caretPos + selectionLength));
DrawableHelper.fill(matrices, caretX, inputFieldBounds.y() - 1, selectionX, inputFieldBounds.yLimit(), 0x803030FF);
}
}
@@ -56,13 +64,29 @@ public class StringControllerElement extends ControllerWidget<IStringController<
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
- if (isAvailable() && inputFieldBounds.isPointInside((int) mouseX, (int) mouseY)) {
- if (!inputFieldFocused) {
- inputFieldFocused = true;
+ if (isAvailable() && getDimension().isPointInside((int) mouseX, (int) mouseY)) {
+ inputFieldFocused = true;
+
+ if (!inputFieldBounds.isPointInside((int) mouseX, (int) mouseY)) {
caretPos = getDefaultCarotPos();
} else {
- int textWidth = (int) mouseX - inputFieldBounds.x();
- caretPos = textRenderer.trimToWidth(control.getString(), textWidth).length();
+ // gets the appropriate carot position for where you click
+ int textX = (int) mouseX - inputFieldBounds.x();
+ int pos = -1;
+ int currentWidth = 0;
+ for (char ch : inputField.toCharArray()) {
+ pos++;
+ int charLength = textRenderer.getWidth(String.valueOf(ch));
+ if (currentWidth + charLength / 2 > textX) { // if more than half way past the characters select in front of that char
+ caretPos = pos;
+ break;
+ } else if (pos == inputField.length() - 1) {
+ // if we have reached the end and no matches, it must be the second half of the char so the last position
+ caretPos = pos + 1;
+ }
+ currentWidth += charLength;
+ }
+
selectionLength = 0;
}
return true;
@@ -83,11 +107,11 @@ public class StringControllerElement extends ControllerWidget<IStringController<
return false;
switch (keyCode) {
- case GLFW.GLFW_KEY_ESCAPE -> {
- inputFieldFocused = false;
+ case InputUtil.GLFW_KEY_ESCAPE, InputUtil.GLFW_KEY_ENTER -> {
+ unfocus();
return true;
}
- case GLFW.GLFW_KEY_LEFT -> {
+ case InputUtil.GLFW_KEY_LEFT -> {
if (Screen.hasShiftDown()) {
if (Screen.hasControlDown()) {
int spaceChar = findSpaceIndex(true);
@@ -98,14 +122,18 @@ public class StringControllerElement extends ControllerWidget<IStringController<
selectionLength += 1;
}
} else {
- if (caretPos > 0)
- caretPos--;
+ if (caretPos > 0) {
+ if (selectionLength != 0)
+ caretPos += Math.min(selectionLength, 0);
+ else
+ caretPos--;
+ }
selectionLength = 0;
}
return true;
}
- case GLFW.GLFW_KEY_RIGHT -> {
+ case InputUtil.GLFW_KEY_RIGHT -> {
if (Screen.hasShiftDown()) {
if (Screen.hasControlDown()) {
int spaceChar = findSpaceIndex(false);
@@ -116,18 +144,22 @@ public class StringControllerElement extends ControllerWidget<IStringController<
selectionLength -= 1;
}
} else {
- if (caretPos < inputField.length())
- caretPos++;
+ if (caretPos < inputField.length()) {
+ if (selectionLength != 0)
+ caretPos += Math.max(selectionLength, 0);
+ else
+ caretPos++;
+ }
selectionLength = 0;
}
return true;
}
- case GLFW.GLFW_KEY_BACKSPACE -> {
+ case InputUtil.GLFW_KEY_BACKSPACE -> {
doBackspace();
return true;
}
- case GLFW.GLFW_KEY_DELETE -> {
+ case InputUtil.GLFW_KEY_DELETE -> {
doDelete();
return true;
}
@@ -172,36 +204,46 @@ public class StringControllerElement extends ControllerWidget<IStringController<
if (selectionLength != 0) {
write("");
} else if (caretPos > 0) {
- inputField.deleteCharAt(caretPos - 1);
- caretPos--;
- updateControl();
+ if (modifyInput(builder -> builder.deleteCharAt(caretPos - 1)))
+ caretPos--;
}
}
protected void doDelete() {
if (caretPos < inputField.length()) {
- inputField.deleteCharAt(caretPos);
- updateControl();
+ modifyInput(builder -> builder.deleteCharAt(caretPos));
}
}
public void write(String string) {
if (selectionLength == 0) {
- string = textRenderer.trimToWidth(string, getMaxLength() - textRenderer.getWidth(inputField.toString()));
+ String trimmed = textRenderer.trimToWidth(string, getMaxLength() - textRenderer.getWidth(inputField));
- inputField.insert(caretPos, string);
- caretPos += string.length();
+ if (modifyInput(builder -> builder.insert(caretPos, trimmed))) {
+ caretPos += trimmed.length();
+ }
} else {
int start = getSelectionStart();
int end = getSelectionEnd();
- string = textRenderer.trimToWidth(string, getMaxLength() - textRenderer.getWidth(inputField.toString()) + textRenderer.getWidth(inputField.substring(start, end)));
+ String trimmed = textRenderer.trimToWidth(string, getMaxLength() - textRenderer.getWidth(inputField) + textRenderer.getWidth(inputField.substring(start, end)));
- inputField.replace(start, end, string);
- caretPos = start + string.length();
- selectionLength = 0;
+ if (modifyInput(builder -> builder.replace(start, end, trimmed))) {
+ caretPos = start + trimmed.length();
+ selectionLength = 0;
+ }
}
- updateControl();
+ }
+
+ public boolean modifyInput(Consumer<StringBuilder> consumer) {
+ StringBuilder temp = new StringBuilder(inputField);
+ consumer.accept(temp);
+ if (!control.isInputValid(temp.toString()))
+ return false;
+ inputField = temp.toString();
+ if (instantApply)
+ updateControl();
+ return true;
}
public int getMaxLength() {
@@ -249,6 +291,7 @@ public class StringControllerElement extends ControllerWidget<IStringController<
public void unfocus() {
super.unfocus();
inputFieldFocused = false;
+ if (!instantApply) updateControl();
}
@Override
@@ -265,7 +308,7 @@ public class StringControllerElement extends ControllerWidget<IStringController<
}
protected void updateControl() {
- control.setFromString(inputField.toString());
+ control.setFromString(inputField);
}
@Override
@@ -278,6 +321,6 @@ public class StringControllerElement extends ControllerWidget<IStringController<
if (!inputFieldFocused && inputField.isEmpty())
return emptyText;
- return super.getValueText();
+ return instantApply || !inputFieldFocused ? control.formatValue() : Text.of(inputField);
}
}
diff --git a/src/client/java/dev/isxander/yacl/gui/controllers/string/number/DoubleFieldController.java b/src/client/java/dev/isxander/yacl/gui/controllers/string/number/DoubleFieldController.java
new file mode 100644
index 0000000..8933df3
--- /dev/null
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/string/number/DoubleFieldController.java
@@ -0,0 +1,105 @@
+package dev.isxander.yacl.gui.controllers.string.number;
+
+import dev.isxander.yacl.api.Option;
+import dev.isxander.yacl.gui.controllers.slider.DoubleSliderController;
+import net.minecraft.text.Text;
+
+import java.math.BigDecimal;
+import java.util.function.Function;
+
+/**
+ * {@inheritDoc}
+ */
+public class DoubleFieldController extends NumberFieldController<Double> {
+ private final double min, max;
+
+ /**
+ * Constructs a double field controller
+ *
+ * @param option option to bind controller to
+ * @param min minimum allowed value (clamped on apply)
+ * @param max maximum allowed value (clamped on apply)
+ * @param formatter display text, not used whilst editing
+ */
+ public DoubleFieldController(Option<Double> option, double min, double max, Function<Double, Text> formatter) {
+ super(option, formatter);
+ this.min = min;
+ this.max = max;
+ }
+
+ /**
+ * Constructs a double field controller.
+ * Uses {@link DoubleSliderController#DEFAULT_FORMATTER} as display text,
+ * not used whilst editing.
+ *
+ * @param option option to bind controller to
+ * @param min minimum allowed value (clamped on apply)
+ * @param max maximum allowed value (clamped on apply)
+ */
+ public DoubleFieldController(Option<Double> option, double min, double max) {
+ this(option, min, max, DoubleSliderController.DEFAULT_FORMATTER);
+ }
+
+ /**
+ * Constructs a double field controller.
+ * Does not have a minimum or a maximum range.
+ *
+ * @param option option to bind controller to
+ * @param formatter display text, not used whilst editing
+ */
+ public DoubleFieldController(Option<Double> option, Function<Double, Text> formatter) {
+ this(option, -Double.MAX_VALUE, Double.MAX_VALUE, formatter);
+ }
+
+ /**
+ * Constructs a double field controller.
+ * Uses {@link DoubleSliderController#DEFAULT_FORMATTER} as display text,
+ * not used whilst editing.
+ * Does not have a minimum or a maximum range.
+ *
+ * @param option option to bind controller to
+ */
+ public DoubleFieldController(Option<Double> option) {
+ this(option, -Double.MAX_VALUE, Double.MAX_VALUE, DoubleSliderController.DEFAULT_FORMATTER);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public double min() {
+ return this.min;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public double max() {
+ return this.max;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getString() {
+ return String.valueOf(option().pendingValue());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setPendingValue(double value) {
+ option().requestSet(value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public double pendingValue() {
+ return option().pendingValue();
+ }
+}
diff --git a/src/client/java/dev/isxander/yacl/gui/controllers/string/number/FloatFieldController.java b/src/client/java/dev/isxander/yacl/gui/controllers/string/number/FloatFieldController.java
new file mode 100644
index 0000000..b1eb3a2
--- /dev/null
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/string/number/FloatFieldController.java
@@ -0,0 +1,105 @@
+package dev.isxander.yacl.gui.controllers.string.number;
+
+import dev.isxander.yacl.api.Option;
+import dev.isxander.yacl.gui.controllers.slider.FloatSliderController;
+import net.minecraft.text.Text;
+
+import java.math.BigDecimal;
+import java.util.function.Function;
+
+/**
+ * {@inheritDoc}
+ */
+public class FloatFieldController extends NumberFieldController<Float> {
+ private final float min, max;
+
+ /**
+ * Constructs a double field controller
+ *
+ * @param option option to bind controller to
+ * @param min minimum allowed value (clamped on apply)
+ * @param max maximum allowed value (clamped on apply)
+ * @param formatter display text, not used whilst editing
+ */
+ public FloatFieldController(Option<Float> option, float min, float max, Function<Float, Text> formatter) {
+ super(option, formatter);
+ this.min = min;
+ this.max = max;
+ }
+
+ /**
+ * Constructs a double field controller.
+ * Uses {@link FloatSliderController#DEFAULT_FORMATTER} as display text,
+ * not used whilst editing.
+ *
+ * @param option option to bind controller to
+ * @param min minimum allowed value (clamped on apply)
+ * @param max maximum allowed value (clamped on apply)
+ */
+ public FloatFieldController(Option<Float> option, float min, float max) {
+ this(option, min, max, FloatSliderController.DEFAULT_FORMATTER);
+ }
+
+ /**
+ * Constructs a double field controller.
+ * Does not have a minimum or a maximum range.
+ *
+ * @param option option to bind controller to
+ * @param formatter display text, not used whilst editing
+ */
+ public FloatFieldController(Option<Float> option, Function<Float, Text> formatter) {
+ this(option, -Float.MAX_VALUE, Float.MAX_VALUE, formatter);
+ }
+
+ /**
+ * Constructs a double field controller.
+ * Uses {@link FloatSliderController#DEFAULT_FORMATTER} as display text,
+ * not used whilst editing.
+ * Does not have a minimum or a maximum range.
+ *
+ * @param option option to bind controller to
+ */
+ public FloatFieldController(Option<Float> option) {
+ this(option, -Float.MAX_VALUE, Float.MAX_VALUE, FloatSliderController.DEFAULT_FORMATTER);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public double min() {
+ return this.min;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public double max() {
+ return this.max;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getString() {
+ return String.valueOf(option().pendingValue());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setPendingValue(double value) {
+ option().requestSet((float) value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public double pendingValue() {
+ return option().pendingValue();
+ }
+}
diff --git a/src/client/java/dev/isxander/yacl/gui/controllers/string/number/IntegerFieldController.java b/src/client/java/dev/isxander/yacl/gui/controllers/string/number/IntegerFieldController.java
new file mode 100644
index 0000000..50eecec
--- /dev/null
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/string/number/IntegerFieldController.java
@@ -0,0 +1,109 @@
+package dev.isxander.yacl.gui.controllers.string.number;
+
+import dev.isxander.yacl.api.Option;
+import dev.isxander.yacl.gui.controllers.slider.IntegerSliderController;
+import net.minecraft.text.Text;
+
+import java.util.function.Function;
+
+/**
+ * {@inheritDoc}
+ */
+public class IntegerFieldController extends NumberFieldController<Integer> {
+ private final int min, max;
+
+ /**
+ * Constructs a double field controller
+ *
+ * @param option option to bind controller to
+ * @param min minimum allowed value (clamped on apply)
+ * @param max maximum allowed value (clamped on apply)
+ * @param formatter display text, not used whilst editing
+ */
+ public IntegerFieldController(Option<Integer> option, int min, int max, Function<Integer, Text> formatter) {
+ super(option, formatter);
+ this.min = min;
+ this.max = max;
+ }
+
+ /**
+ * Constructs a double field controller.
+ * Uses {@link IntegerSliderController#DEFAULT_FORMATTER} as display text,
+ * not used whilst editing.
+ *
+ * @param option option to bind controller to
+ * @param min minimum allowed value (clamped on apply)
+ * @param max maximum allowed value (clamped on apply)
+ */
+ public IntegerFieldController(Option<Integer> option, int min, int max) {
+ this(option, min, max, IntegerSliderController.DEFAULT_FORMATTER);
+ }
+
+ /**
+ * Constructs a double field controller.
+ * Does not have a minimum or a maximum range.
+ *
+ * @param option option to bind controller to
+ * @param formatter display text, not used whilst editing
+ */
+ public IntegerFieldController(Option<Integer> option, Function<Integer, Text> formatter) {
+ this(option, -Integer.MAX_VALUE, Integer.MAX_VALUE, formatter);
+ }
+
+ /**
+ * Constructs a double field controller.
+ * Uses {@link IntegerSliderController#DEFAULT_FORMATTER} as display text,
+ * not used whilst editing.
+ * Does not have a minimum or a maximum range.
+ *
+ * @param option option to bind controller to
+ */
+ public IntegerFieldController(Option<Integer> option) {
+ this(option, -Integer.MAX_VALUE, Integer.MAX_VALUE, IntegerSliderController.DEFAULT_FORMATTER);
+ }
+
+ @Override
+ public boolean isInputValid(String input) {
+ return input.matches("\\d+|-|");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public double min() {
+ return this.min;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public double max() {
+ return this.max;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getString() {
+ return String.valueOf(option().pendingValue());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setPendingValue(double value) {
+ option().requestSet((int) value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public double pendingValue() {
+ return option().pendingValue();
+ }
+}
diff --git a/src/client/java/dev/isxander/yacl/gui/controllers/string/number/LongFieldController.java b/src/client/java/dev/isxander/yacl/gui/controllers/string/number/LongFieldController.java
new file mode 100644
index 0000000..516de74
--- /dev/null
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/string/number/LongFieldController.java
@@ -0,0 +1,109 @@
+package dev.isxander.yacl.gui.controllers.string.number;
+
+import dev.isxander.yacl.api.Option;
+import dev.isxander.yacl.gui.controllers.slider.LongSliderController;
+import net.minecraft.text.Text;
+
+import java.util.function.Function;
+
+/**
+ * {@inheritDoc}
+ */
+public class LongFieldController extends NumberFieldController<Long> {
+ private final long min, max;
+
+ /**
+ * Constructs a double field controller
+ *
+ * @param option option to bind controller to
+ * @param min minimum allowed value (clamped on apply)
+ * @param max maximum allowed value (clamped on apply)
+ * @param formatter display text, not used whilst editing
+ */
+ public LongFieldController(Option<Long> option, long min, long max, Function<Long, Text> formatter) {
+ super(option, formatter);
+ this.min = min;
+ this.max = max;
+ }
+
+ /**
+ * Constructs a double field controller.
+ * Uses {@link LongSliderController#DEFAULT_FORMATTER} as display text,
+ * not used whilst editing.
+ *
+ * @param option option to bind controller to
+ * @param min minimum allowed value (clamped on apply)
+ * @param max maximum allowed value (clamped on apply)
+ */
+ public LongFieldController(Option<Long> option, long min, long max) {
+ this(option, min, max, LongSliderController.DEFAULT_FORMATTER);
+ }
+
+ /**
+ * Constructs a double field controller.
+ * Does not have a minimum or a maximum range.
+ *
+ * @param option option to bind controller to
+ * @param formatter display text, not used whilst editing
+ */
+ public LongFieldController(Option<Long> option, Function<Long, Text> formatter) {
+ this(option, -Long.MAX_VALUE, Long.MAX_VALUE, formatter);
+ }
+
+ /**
+ * Constructs a double field controller.
+ * Uses {@link LongSliderController#DEFAULT_FORMATTER} as display text,
+ * not used whilst editing.
+ * Does not have a minimum or a maximum range.
+ *
+ * @param option option to bind controller to
+ */
+ public LongFieldController(Option<Long> option) {
+ this(option, -Long.MAX_VALUE, Long.MAX_VALUE, LongSliderController.DEFAULT_FORMATTER);
+ }
+
+ @Override
+ public boolean isInputValid(String input) {
+ return input.matches("\\d+|-|");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public double min() {
+ return this.min;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public double max() {
+ return this.max;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getString() {
+ return String.valueOf(option().pendingValue());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setPendingValue(double value) {
+ option().requestSet((long) value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public double pendingValue() {
+ return option().pendingValue();
+ }
+}
diff --git a/src/client/java/dev/isxander/yacl/gui/controllers/string/number/NumberFieldController.java b/src/client/java/dev/isxander/yacl/gui/controllers/string/number/NumberFieldController.java
new file mode 100644
index 0000000..bf0354a
--- /dev/null
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/string/number/NumberFieldController.java
@@ -0,0 +1,69 @@
+package dev.isxander.yacl.gui.controllers.string.number;
+
+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 dev.isxander.yacl.gui.controllers.slider.ISliderController;
+import dev.isxander.yacl.gui.controllers.string.IStringController;
+import dev.isxander.yacl.gui.controllers.string.StringControllerElement;
+import net.minecraft.text.Text;
+import net.minecraft.util.math.MathHelper;
+
+import java.text.DecimalFormatSymbols;
+import java.util.function.Function;
+
+/**
+ * Controller that allows you to enter in numbers using a text field.
+ *
+ * @param <T> number type
+ */
+public abstract class NumberFieldController<T extends Number> implements ISliderController<T>, IStringController<T> {
+ private final Option<T> option;
+ private final Function<T, Text> displayFormatter;
+
+ public NumberFieldController(Option<T> option, Function<T, Text> displayFormatter) {
+ this.option = option;
+ this.displayFormatter = displayFormatter;
+ }
+
+ @Override
+ public Option<T> option() {
+ return this.option;
+ }
+
+ @Override
+ public void setFromString(String value) {
+ if (value.isEmpty() || value.equals(".") || value.equals("-")) value = "0";
+ setPendingValue(MathHelper.clamp(Double.parseDouble(cleanupNumberString(value)), min(), max()));
+ }
+
+ @Override
+ public double pendingValue() {
+ return option().pendingValue().doubleValue();
+ }
+
+ @Override
+ public boolean isInputValid(String input) {
+ return input.matches("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)|[.]||-");
+ }
+
+ @Override
+ public Text formatValue() {
+ return displayFormatter.apply(option().pendingValue());
+ }
+
+ @Override
+ public AbstractWidget provideWidget(YACLScreen screen, Dimension<Integer> widgetDimension) {
+ return new StringControllerElement(this, screen, widgetDimension, false);
+ }
+
+ protected String cleanupNumberString(String number) {
+ return number.replace(String.valueOf(DecimalFormatSymbols.getInstance().getGroupingSeparator()), "");
+ }
+
+ @Override
+ public double interval() {
+ return -1;
+ }
+}
diff --git a/src/client/java/dev/isxander/yacl/gui/controllers/string/number/package-info.java b/src/client/java/dev/isxander/yacl/gui/controllers/string/number/package-info.java
new file mode 100644
index 0000000..86b9314
--- /dev/null
+++ b/src/client/java/dev/isxander/yacl/gui/controllers/string/number/package-info.java
@@ -0,0 +1,10 @@
+/**
+ * This package contains implementations of input fields for different number types
+ * <ul>
+ * <li>For doubles: {@link dev.isxander.yacl.gui.controllers.string.number.DoubleFieldController}</li>
+ * <li>For floats: {@link dev.isxander.yacl.gui.controllers.string.number.FloatFieldController}</li>
+ * <li>For integers: {@link dev.isxander.yacl.gui.controllers.string.number.IntegerFieldController}</li>
+ * <li>For longs: {@link dev.isxander.yacl.gui.controllers.string.number.LongFieldController}</li>
+ * </ul>
+ */
+package dev.isxander.yacl.gui.controllers.string.number;
diff --git a/src/main/java/dev/isxander/yacl/impl/ButtonOptionImpl.java b/src/client/java/dev/isxander/yacl/impl/ButtonOptionImpl.java
index dcb9c7a..dcb9c7a 100644
--- a/src/main/java/dev/isxander/yacl/impl/ButtonOptionImpl.java
+++ b/src/client/java/dev/isxander/yacl/impl/ButtonOptionImpl.java
diff --git a/src/main/java/dev/isxander/yacl/impl/ConfigCategoryImpl.java b/src/client/java/dev/isxander/yacl/impl/ConfigCategoryImpl.java
index 971fecf..971fecf 100644
--- a/src/main/java/dev/isxander/yacl/impl/ConfigCategoryImpl.java
+++ b/src/client/java/dev/isxander/yacl/impl/ConfigCategoryImpl.java
diff --git a/src/main/java/dev/isxander/yacl/impl/GenericBindingImpl.java b/src/client/java/dev/isxander/yacl/impl/GenericBindingImpl.java
index 1867bb6..1867bb6 100644
--- a/src/main/java/dev/isxander/yacl/impl/GenericBindingImpl.java
+++ b/src/client/java/dev/isxander/yacl/impl/GenericBindingImpl.java
diff --git a/src/main/java/dev/isxander/yacl/impl/OptionGroupImpl.java b/src/client/java/dev/isxander/yacl/impl/OptionGroupImpl.java
index 58bc96b..58bc96b 100644
--- a/src/main/java/dev/isxander/yacl/impl/OptionGroupImpl.java
+++ b/src/client/java/dev/isxander/yacl/impl/OptionGroupImpl.java
diff --git a/src/main/java/dev/isxander/yacl/impl/OptionImpl.java b/src/client/java/dev/isxander/yacl/impl/OptionImpl.java
index c76f115..90158c7 100644
--- a/src/main/java/dev/isxander/yacl/impl/OptionImpl.java
+++ b/src/client/java/dev/isxander/yacl/impl/OptionImpl.java
@@ -6,7 +6,6 @@ import dev.isxander.yacl.api.Controller;
import dev.isxander.yacl.api.Option;
import dev.isxander.yacl.api.OptionFlag;
import net.minecraft.text.Text;
-import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/src/main/java/dev/isxander/yacl/impl/PlaceholderCategoryImpl.java b/src/client/java/dev/isxander/yacl/impl/PlaceholderCategoryImpl.java
index a5180ad..a5180ad 100644
--- a/src/main/java/dev/isxander/yacl/impl/PlaceholderCategoryImpl.java
+++ b/src/client/java/dev/isxander/yacl/impl/PlaceholderCategoryImpl.java
diff --git a/src/main/java/dev/isxander/yacl/impl/YetAnotherConfigLibImpl.java b/src/client/java/dev/isxander/yacl/impl/YetAnotherConfigLibImpl.java
index eb23eac..eb23eac 100644
--- a/src/main/java/dev/isxander/yacl/impl/YetAnotherConfigLibImpl.java
+++ b/src/client/java/dev/isxander/yacl/impl/YetAnotherConfigLibImpl.java
diff --git a/src/main/java/dev/isxander/yacl/mixin/SimpleOptionAccessor.java b/src/client/java/dev/isxander/yacl/mixin/client/SimpleOptionAccessor.java
index 9207225..a48c808 100644
--- a/src/main/java/dev/isxander/yacl/mixin/SimpleOptionAccessor.java
+++ b/src/client/java/dev/isxander/yacl/mixin/client/SimpleOptionAccessor.java
@@ -1,4 +1,4 @@
-package dev.isxander.yacl.mixin;
+package dev.isxander.yacl.mixin.client;
import net.minecraft.client.option.SimpleOption;
import org.spongepowered.asm.mixin.Mixin;
diff --git a/src/main/resources/yet-another-config-lib.mixins.json b/src/client/resources/yet-another-config-lib.client.mixins.json
index cb96c48..2367a67 100644
--- a/src/main/resources/yet-another-config-lib.mixins.json
+++ b/src/client/resources/yet-another-config-lib.client.mixins.json
@@ -1,6 +1,6 @@
{
"required": true,
- "package": "dev.isxander.yacl.mixin",
+ "package": "dev.isxander.yacl.mixin.client",
"compatibilityLevel": "JAVA_17",
"injectors": {
"defaultRequire": 1
diff --git a/src/main/java/dev/isxander/yacl/config/ConfigInstance.java b/src/main/java/dev/isxander/yacl/config/ConfigInstance.java
index a7c013c..aa67865 100644
--- a/src/main/java/dev/isxander/yacl/config/ConfigInstance.java
+++ b/src/main/java/dev/isxander/yacl/config/ConfigInstance.java
@@ -1,9 +1,9 @@
package dev.isxander.yacl.config;
-import dev.isxander.yacl.api.YetAnotherConfigLib;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationTargetException;
-import java.util.function.BiFunction;
/**
* Responsible for handing the actual config data type.
@@ -30,6 +30,9 @@ public abstract class ConfigInstance<T> {
}
}
+ public abstract void save();
+ public abstract void load();
+
public T getConfig() {
return this.instance;
}
@@ -45,11 +48,4 @@ public abstract class ConfigInstance<T> {
public Class<T> getConfigClass() {
return this.configClass;
}
-
- public YetAnotherConfigLib buildConfig(BiFunction<ConfigInstance<T>, YetAnotherConfigLib.Builder, YetAnotherConfigLib.Builder> builder) {
- return builder.apply(this, YetAnotherConfigLib.createBuilder().save(this::save)).build();
- }
-
- public abstract void save();
- public abstract void load();
}
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/EnumController.java b/src/main/java/dev/isxander/yacl/gui/controllers/EnumController.java
deleted file mode 100644
index ebad4ae..0000000
--- a/src/main/java/dev/isxander/yacl/gui/controllers/EnumController.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package dev.isxander.yacl.gui.controllers;
-
-import dev.isxander.yacl.api.NameableEnum;
-import dev.isxander.yacl.api.Option;
-import dev.isxander.yacl.gui.controllers.cycling.CyclingListController;
-import net.minecraft.text.Text;
-import net.minecraft.util.TranslatableOption;
-
-import java.util.Arrays;
-import java.util.function.Function;
-
-@Deprecated
-public class EnumController<T extends Enum<T>> extends CyclingListController<T> {
- public static <T extends Enum<T>> Function<T, Text> getDefaultFormatter() {
- return value -> {
- if (value instanceof NameableEnum nameableEnum)
- return nameableEnum.getDisplayName();
- if (value instanceof TranslatableOption translatableOption)
- return translatableOption.getText();
- return Text.of(value.toString());
- };
- }
-
- public EnumController(Option<T> option) {
- this(option, getDefaultFormatter());
- }
-
- public EnumController(Option<T> option, Function<T, Text> valueFormatter) {
- this(option, valueFormatter, option.typeClass().getEnumConstants());
- }
-
- public EnumController(Option<T> option, Function<T, Text> valueFormatter, T[] availableValues) {
- super(option, Arrays.asList(availableValues), valueFormatter);
- }
-}
diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json
index fc5a14f..90889a0 100644
--- a/src/main/resources/fabric.mod.json
+++ b/src/main/resources/fabric.mod.json
@@ -14,17 +14,21 @@
},
"icon": "yacl-128x.png",
"license": "LGPL-3.0-or-later",
- "environment": "client",
+ "environment": "*",
"entrypoints": {
},
"depends": {
"fabricloader": ">=0.14.0",
- "minecraft": "1.19.x",
- "java": ">=17"
+ "minecraft": "~1.19.3-beta.1",
+ "java": ">=17",
+ "fabric-resource-loader-v0": "*"
},
"mixins": [
- "yet-another-config-lib.mixins.json"
+ {
+ "config": "yet-another-config-lib.client.mixins.json",
+ "environment": "client"
+ }
],
"accessWidener": "yacl.accesswidener",
"custom": {
diff --git a/src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java b/src/testmod/java/dev/isxander/yacl/test/GuiTest.java
index 596a0bf..492a573 100644
--- a/src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java
+++ b/src/testmod/java/dev/isxander/yacl/test/GuiTest.java
@@ -1,7 +1,5 @@
package dev.isxander.yacl.test;
-import com.terraformersmc.modmenu.api.ConfigScreenFactory;
-import com.terraformersmc.modmenu.api.ModMenuApi;
import dev.isxander.yacl.api.*;
import dev.isxander.yacl.gui.RequireRestartScreen;
import dev.isxander.yacl.gui.controllers.*;
@@ -11,6 +9,10 @@ import dev.isxander.yacl.gui.controllers.slider.FloatSliderController;
import dev.isxander.yacl.gui.controllers.slider.IntegerSliderController;
import dev.isxander.yacl.gui.controllers.slider.LongSliderController;
import dev.isxander.yacl.gui.controllers.string.StringController;
+import dev.isxander.yacl.gui.controllers.string.number.DoubleFieldController;
+import dev.isxander.yacl.gui.controllers.string.number.FloatFieldController;
+import dev.isxander.yacl.gui.controllers.string.number.IntegerFieldController;
+import dev.isxander.yacl.gui.controllers.string.number.LongFieldController;
import dev.isxander.yacl.test.config.ConfigData;
import dev.isxander.yacl.test.config.Entrypoint;
import net.minecraft.client.MinecraftClient;
@@ -23,10 +25,9 @@ import net.minecraft.text.Text;
import java.awt.*;
-public class ModMenuIntegration implements ModMenuApi {
- @Override
- public ConfigScreenFactory<?> getModConfigScreenFactory() {
- return (parent) -> Entrypoint.getConfig().buildConfig((config, builder) -> builder
+public class GuiTest {
+ public static Screen getModConfigScreenFactory(Screen parent) {
+ return YetAnotherConfigLib.create(Entrypoint.getConfig(), (defaults, config, builder) -> builder
.title(Text.of("Test Suites"))
.category(ConfigCategory.createBuilder()
.name(Text.of("Suites"))
@@ -55,8 +56,8 @@ public class ModMenuIntegration implements ModMenuApi {
.generateScreen(parent);
}
- private Screen getFullTestSuite(Screen parent) {
- return Entrypoint.getConfig().buildConfig((config, builder) -> builder
+ private static Screen getFullTestSuite(Screen parent) {
+ return YetAnotherConfigLib.create(Entrypoint.getConfig(), (defaults, config, builder) -> builder
.title(Text.of("Test GUI"))
.category(ConfigCategory.createBuilder()
.name(Text.of("Control Examples"))
@@ -69,9 +70,9 @@ public class ModMenuIntegration implements ModMenuApi {
.name(Text.of("Boolean Toggle"))
.tooltip(value -> Text.of("A simple toggle button that contains the value '" + value + "'"))
.binding(
- config.getDefaults().booleanToggle,
- () -> config.getConfig().booleanToggle,
- (value) -> config.getConfig().booleanToggle = value
+ defaults.booleanToggle,
+ () -> config.booleanToggle,
+ (value) -> config.booleanToggle = value
)
.controller(BooleanController::new)
.flag(OptionFlag.GAME_RESTART)
@@ -81,19 +82,19 @@ public class ModMenuIntegration implements ModMenuApi {
.name(Text.of("Custom Boolean Toggle"))
.tooltip(Text.of("You can customize these controllers like this!"))
.binding(
- config.getDefaults().customBooleanToggle,
- () -> config.getConfig().customBooleanToggle,
- (value) -> config.getConfig().customBooleanToggle = value
+ defaults.customBooleanToggle,
+ () -> config.customBooleanToggle,
+ (value) -> config.customBooleanToggle = value
)
.controller(opt -> new BooleanController(opt, state -> state ? Text.of("Amazing") : Text.of("Not Amazing"), true))
.build())
.option(Option.createBuilder(boolean.class)
- .name(Text.of("Tick Box"))
+ .name(Text.of("Tick Box aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
.tooltip(Text.of("There are even alternate methods of displaying the same data type!"))
.binding(
- config.getDefaults().tickbox,
- () -> config.getConfig().tickbox,
- (value) -> config.getConfig().tickbox = value
+ defaults.tickbox,
+ () -> config.tickbox,
+ (value) -> config.tickbox = value
)
.controller(TickBoxController::new)
.build())
@@ -104,9 +105,9 @@ public class ModMenuIntegration implements ModMenuApi {
.name(Text.of("Int Slider that is cut off because the slider"))
.instant(true)
.binding(
- config.getDefaults().intSlider,
- () -> config.getConfig().intSlider,
- value -> config.getConfig().intSlider = value
+ defaults.intSlider,
+ () -> config.intSlider,
+ value -> config.intSlider = value
)
.controller(opt -> new IntegerSliderController(opt, 0, 3, 1))
@@ -114,27 +115,27 @@ public class ModMenuIntegration implements ModMenuApi {
.option(Option.createBuilder(double.class)
.name(Text.of("Double Slider"))
.binding(
- config.getDefaults().doubleSlider,
- () -> config.getConfig().doubleSlider,
- (value) -> config.getConfig().doubleSlider = value
+ defaults.doubleSlider,
+ () -> config.doubleSlider,
+ (value) -> config.doubleSlider = value
)
.controller(opt -> new DoubleSliderController(opt, 0, 3, 0.05))
.build())
.option(Option.createBuilder(float.class)
.name(Text.of("Float Slider"))
.binding(
- config.getDefaults().floatSlider,
- () -> config.getConfig().floatSlider,
- (value) -> config.getConfig().floatSlider = value
+ defaults.floatSlider,
+ () -> config.floatSlider,
+ (value) -> config.floatSlider = value
)
.controller(opt -> new FloatSliderController(opt, 0, 3, 0.1f))
.build())
.option(Option.createBuilder(long.class)
.name(Text.of("Long Slider"))
.binding(
- config.getDefaults().longSlider,
- () -> config.getConfig().longSlider,
- (value) -> config.getConfig().longSlider = value
+ defaults.longSlider,
+ () -> config.longSlider,
+ (value) -> config.longSlider = value
)
.controller(opt -> new LongSliderController(opt, 0, 1_000_000, 100))
.build())
@@ -144,30 +145,69 @@ public class ModMenuIntegration implements ModMenuApi {
.option(Option.createBuilder(String.class)
.name(Text.of("Text Option"))
.binding(
- config.getDefaults().textField,
- () -> config.getConfig().textField,
- value -> config.getConfig().textField = value
+ defaults.textField,
+ () -> config.textField,
+ value -> config.textField = value
)
.controller(StringController::new)
.build())
.option(Option.createBuilder(Color.class)
.name(Text.of("Color Option"))
.binding(
- config.getDefaults().colorOption,
- () -> config.getConfig().colorOption,
- value -> config.getConfig().colorOption = value
+ defaults.colorOption,
+ () -> config.colorOption,
+ value -> config.colorOption = value
)
.controller(ColorController::new)
.build())
.build())
.group(OptionGroup.createBuilder()
+ .name(Text.of("Number Fields"))
+ .option(Option.createBuilder(double.class)
+ .name(Text.of("Double Field"))
+ .binding(
+ defaults.doubleField,
+ () -> config.doubleField,
+ value -> config.doubleField = value
+ )
+ .controller(DoubleFieldController::new)
+ .build())
+ .option(Option.createBuilder(float.class)
+ .name(Text.of("Float Field"))
+ .binding(
+ defaults.floatField,
+ () -> config.floatField,
+ value -> config.floatField = value
+ )
+ .controller(FloatFieldController::new)
+ .build())
+ .option(Option.createBuilder(int.class)
+ .name(Text.of("Integer Field"))
+ .binding(
+ defaults.intField,
+ () -> config.intField,
+ value -> config.intField = value
+ )
+ .controller(IntegerFieldController::new)
+ .build())
+ .option(Option.createBuilder(long.class)
+ .name(Text.of("Long Field"))
+ .binding(
+ defaults.longField,
+ () -> config.longField,
+ value -> config.longField = value
+ )
+ .controller(LongFieldController::new)
+ .build())
+ .build())
+ .group(OptionGroup.createBuilder()
.name(Text.of("Enum Controllers"))
.option(Option.createBuilder(ConfigData.Alphabet.class)
.name(Text.of("Enum Cycler"))
.binding(
- config.getDefaults().enumOption,
- () -> config.getConfig().enumOption,
- (value) -> config.getConfig().enumOption = value
+ defaults.enumOption,
+ () -> config.enumOption,
+ (value) -> config.enumOption = value
)
.controller(EnumController::new)
.build())
@@ -215,9 +255,9 @@ public class ModMenuIntegration implements ModMenuApi {
.option(Option.createBuilder(boolean.class)
.name(Text.of("Root Test"))
.binding(
- config.getDefaults().groupTestRoot,
- () -> config.getConfig().groupTestRoot,
- value -> config.getConfig().groupTestRoot = value
+ defaults.groupTestRoot,
+ () -> config.groupTestRoot,
+ value -> config.groupTestRoot = value
)
.controller(TickBoxController::new)
.build())
@@ -226,18 +266,18 @@ public class ModMenuIntegration implements ModMenuApi {
.option(Option.createBuilder(boolean.class)
.name(Text.of("First Group Test 1"))
.binding(
- config.getDefaults().groupTestFirstGroup,
- () -> config.getConfig().groupTestFirstGroup,
- value -> config.getConfig().groupTestFirstGroup = value
+ defaults.groupTestFirstGroup,
+ () -> config.groupTestFirstGroup,
+ value -> config.groupTestFirstGroup = value
)
.controller(TickBoxController::new)
.build())
.option(Option.createBuilder(boolean.class)
.name(Text.of("First Group Test 2"))
.binding(
- config.getDefaults().groupTestFirstGroup2,
- () -> config.getConfig().groupTestFirstGroup2,
- value -> config.getConfig().groupTestFirstGroup2 = value
+ defaults.groupTestFirstGroup2,
+ () -> config.groupTestFirstGroup2,
+ value -> config.groupTestFirstGroup2 = value
)
.controller(TickBoxController::new)
.build())
@@ -247,9 +287,9 @@ public class ModMenuIntegration implements ModMenuApi {
.option(Option.createBuilder(boolean.class)
.name(Text.of("Second Group Test"))
.binding(
- config.getDefaults().groupTestSecondGroup,
- () -> config.getConfig().groupTestSecondGroup,
- value -> config.getConfig().groupTestSecondGroup = value
+ defaults.groupTestSecondGroup,
+ () -> config.groupTestSecondGroup,
+ value -> config.groupTestSecondGroup = value
)
.controller(TickBoxController::new)
.build())
@@ -260,9 +300,9 @@ public class ModMenuIntegration implements ModMenuApi {
.option(Option.createBuilder(int.class)
.name(Text.of("Int Slider that is cut off because the slider"))
.binding(
- config.getDefaults().scrollingSlider,
- () -> config.getConfig().scrollingSlider,
- (value) -> config.getConfig().scrollingSlider = value
+ defaults.scrollingSlider,
+ () -> config.scrollingSlider,
+ (value) -> config.scrollingSlider = value
)
.controller(opt -> new IntegerSliderController(opt, 0, 10, 1))
.build())
@@ -334,14 +374,14 @@ public class ModMenuIntegration implements ModMenuApi {
.build())
.save(() -> {
MinecraftClient.getInstance().options.write();
- config.save();
+ Entrypoint.getConfig().save();
})
)
.generateScreen(parent);
}
- private Screen getDisabledTest(Screen parent) {
- return Entrypoint.getConfig().buildConfig((config, builder) -> builder
+ private static Screen getDisabledTest(Screen parent) {
+ return YetAnotherConfigLib.create(Entrypoint.getConfig(), (defaults, config, builder) -> builder
.title(Text.empty())
.category(ConfigCategory.createBuilder()
.name(Text.of("Disabled Test"))
@@ -373,8 +413,8 @@ public class ModMenuIntegration implements ModMenuApi {
.generateScreen(parent);
}
- private Screen getWikiBasic(Screen parent) {
- return Entrypoint.getConfig().buildConfig((config, builder) -> builder
+ private static Screen getWikiBasic(Screen parent) {
+ return YetAnotherConfigLib.create(Entrypoint.getConfig(), (defaults, config, builder) -> builder
.title(Text.of("Mod Name"))
.category(ConfigCategory.createBuilder()
.name(Text.of("My Category"))
@@ -383,9 +423,9 @@ public class ModMenuIntegration implements ModMenuApi {
.name(Text.of("My Boolean Option"))
.tooltip(Text.of("This option displays the basic capabilities of YetAnotherConfigLib")) // optional
.binding(
- config.getDefaults().booleanToggle, // default
- () -> config.getConfig().booleanToggle, // getter
- newValue -> config.getConfig().booleanToggle = newValue // setter
+ defaults.booleanToggle, // default
+ () -> config.booleanToggle, // getter
+ newValue -> config.booleanToggle = newValue // setter
)
.controller(BooleanController::new)
.build())
@@ -394,8 +434,8 @@ public class ModMenuIntegration implements ModMenuApi {
.generateScreen(parent);
}
- private Screen getWikiGroups(Screen parent) {
- return Entrypoint.getConfig().buildConfig((config, builder) -> builder
+ private static Screen getWikiGroups(Screen parent) {
+ return YetAnotherConfigLib.create(Entrypoint.getConfig(), (defaults, config, builder) -> builder
.title(Text.of("Mod Name"))
.category(ConfigCategory.createBuilder()
.name(Text.of("My Category"))
@@ -406,9 +446,9 @@ public class ModMenuIntegration implements ModMenuApi {
.name(Text.of("My Boolean Option"))
.tooltip(Text.of("This option displays the basic capabilities of YetAnotherConfigLib")) // optional
.binding(
- config.getDefaults().booleanToggle, // default
- () -> config.getConfig().booleanToggle, // getter
- newValue -> config.getConfig().booleanToggle = newValue // setter
+ defaults.booleanToggle, // default
+ () -> config.booleanToggle, // getter
+ newValue -> config.booleanToggle = newValue // setter
)
.controller(BooleanController::new)
.build())
@@ -417,21 +457,4 @@ public class ModMenuIntegration implements ModMenuApi {
)
.generateScreen(parent);
}
-
- private ConfigScreenFactory<?> getWikiButton() {
- return (parent) -> Entrypoint.getConfig().buildConfig((config, builder) -> builder
- .title(Text.of("Mod Name"))
- .category(ConfigCategory.createBuilder()
- .name(Text.of("My Category"))
- .tooltip(Text.of("This displays when you hover over a category button")) // optional
- .option(ButtonOption.createBuilder()
- .name(Text.of("Pressable Button"))
- .tooltip(Text.of("This is so easy!")) // optional
- .action(screen -> {})
- .controller(ActionController::new)
- .build())
- .build())
- )
- .generateScreen(parent);
- }
}
diff --git a/src/testmod/java/dev/isxander/yacl/test/config/ConfigData.java b/src/testmod/java/dev/isxander/yacl/test/config/ConfigData.java
index 35e57dd..4eedd9f 100644
--- a/src/testmod/java/dev/isxander/yacl/test/config/ConfigData.java
+++ b/src/testmod/java/dev/isxander/yacl/test/config/ConfigData.java
@@ -14,6 +14,10 @@ public class ConfigData {
@ConfigEntry public long longSlider = 0;
@ConfigEntry public String textField = "Hello";
@ConfigEntry public Color colorOption = Color.red;
+ @ConfigEntry public double doubleField = 0.5;
+ @ConfigEntry public float floatField = 0.5f;
+ @ConfigEntry public int intField = 5;
+ @ConfigEntry public long longField = 5;
@ConfigEntry public Alphabet enumOption = Alphabet.A;
@ConfigEntry public boolean groupTestRoot = false;
diff --git a/src/testmod/java/dev/isxander/yacl/test/config/Entrypoint.java b/src/testmod/java/dev/isxander/yacl/test/config/Entrypoint.java
index 39baffa..c71f592 100644
--- a/src/testmod/java/dev/isxander/yacl/test/config/Entrypoint.java
+++ b/src/testmod/java/dev/isxander/yacl/test/config/Entrypoint.java
@@ -1,13 +1,12 @@
package dev.isxander.yacl.test.config;
-import com.google.gson.Gson;
import dev.isxander.yacl.config.ConfigInstance;
import dev.isxander.yacl.config.GsonConfigInstance;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.loader.api.FabricLoader;
public class Entrypoint implements ClientModInitializer {
- private static GsonConfigInstance<ConfigData> config;
+ private static ConfigInstance<ConfigData> config;
@Override
public void onInitializeClient() {
diff --git a/src/testmod/java/dev/isxander/yacl/test/mixins/TitleScreenMixin.java b/src/testmod/java/dev/isxander/yacl/test/mixins/TitleScreenMixin.java
new file mode 100644
index 0000000..2635eaf
--- /dev/null
+++ b/src/testmod/java/dev/isxander/yacl/test/mixins/TitleScreenMixin.java
@@ -0,0 +1,26 @@
+package dev.isxander.yacl.test.mixins;
+
+import dev.isxander.yacl.test.GuiTest;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.screen.TitleScreen;
+import net.minecraft.client.gui.widget.ButtonWidget;
+import net.minecraft.text.Text;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(TitleScreen.class)
+public abstract class TitleScreenMixin extends Screen {
+ protected TitleScreenMixin(Text title) {
+ super(title);
+ }
+
+ @Inject(method = "init", at = @At("RETURN"))
+ private void injectTestButton(CallbackInfo ci) {
+ addDrawableChild(ButtonWidget.builder(Text.of("YACL"), button -> client.setScreen(GuiTest.getModConfigScreenFactory(client.currentScreen)))
+ .position(0, 0)
+ .width(50)
+ .build());
+ }
+}
diff --git a/src/testmod/resources/fabric.mod.json b/src/testmod/resources/fabric.mod.json
index 1360a5e..5fe0919 100644
--- a/src/testmod/resources/fabric.mod.json
+++ b/src/testmod/resources/fabric.mod.json
@@ -11,15 +11,12 @@
"entrypoints": {
"client": [
"dev.isxander.yacl.test.config.Entrypoint"
- ],
- "modmenu": [
- "dev.isxander.yacl.test.ModMenuIntegration"
]
},
"depends": {
- "fabricloader": ">=0.14.0",
- "minecraft": "1.19.x",
- "java": ">=17",
- "fabric-resource-loader-v0": "*"
- }
+ "yet-another-config-lib": "*"
+ },
+ "mixins": [
+ "yet-another-config-lib.test.mixins.json"
+ ]
}
diff --git a/src/testmod/resources/yet-another-config-lib.test.mixins.json b/src/testmod/resources/yet-another-config-lib.test.mixins.json
new file mode 100644
index 0000000..9287cdd
--- /dev/null
+++ b/src/testmod/resources/yet-another-config-lib.test.mixins.json
@@ -0,0 +1,11 @@
+{
+ "required": true,
+ "package": "dev.isxander.yacl.test.mixins",
+ "compatibilityLevel": "JAVA_17",
+ "injectors": {
+ "defaultRequire": 1
+ },
+ "client": [
+ "TitleScreenMixin"
+ ]
+}