aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.gradle.kts2
-rw-r--r--src/main/java/dev/isxander/yacl/api/ButtonOption.java41
-rw-r--r--src/main/java/dev/isxander/yacl/api/Option.java19
-rw-r--r--src/main/java/dev/isxander/yacl/gui/AbstractWidget.java17
-rw-r--r--src/main/java/dev/isxander/yacl/gui/CategoryListWidget.java10
-rw-r--r--src/main/java/dev/isxander/yacl/gui/OptionListWidget.java4
-rw-r--r--src/main/java/dev/isxander/yacl/gui/TooltipButtonWidget.java9
-rw-r--r--src/main/java/dev/isxander/yacl/gui/YACLScreen.java58
-rw-r--r--src/main/java/dev/isxander/yacl/gui/controllers/ActionController.java2
-rw-r--r--src/main/java/dev/isxander/yacl/gui/controllers/BooleanController.java2
-rw-r--r--src/main/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java26
-rw-r--r--src/main/java/dev/isxander/yacl/gui/controllers/EnumController.java2
-rw-r--r--src/main/java/dev/isxander/yacl/gui/controllers/LabelController.java2
-rw-r--r--src/main/java/dev/isxander/yacl/gui/controllers/TickBoxController.java16
-rw-r--r--src/main/java/dev/isxander/yacl/gui/controllers/slider/SliderControllerElement.java10
-rw-r--r--src/main/java/dev/isxander/yacl/gui/controllers/string/StringControllerElement.java2
-rw-r--r--src/main/java/dev/isxander/yacl/impl/ButtonOptionImpl.java8
-rw-r--r--src/main/java/dev/isxander/yacl/impl/OptionImpl.java8
-rw-r--r--src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java37
19 files changed, 236 insertions, 39 deletions
diff --git a/build.gradle.kts b/build.gradle.kts
index 113b2e2..ca4c855 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -16,7 +16,7 @@ plugins {
val ciRun = System.getenv().containsKey("GITHUB_ACTIONS")
group = "dev.isxander"
-version = "1.1.2"
+version = "1.2.0"
if (ciRun)
version = "$version-SNAPSHOT"
diff --git a/src/main/java/dev/isxander/yacl/api/ButtonOption.java b/src/main/java/dev/isxander/yacl/api/ButtonOption.java
index f3d1e6b..519131e 100644
--- a/src/main/java/dev/isxander/yacl/api/ButtonOption.java
+++ b/src/main/java/dev/isxander/yacl/api/ButtonOption.java
@@ -13,6 +13,9 @@ import java.util.function.Consumer;
import java.util.function.Function;
public interface ButtonOption extends Option<Consumer<YACLScreen>> {
+ /**
+ * Action to be executed upon button press
+ */
Consumer<YACLScreen> action();
static Builder createBuilder() {
@@ -22,6 +25,7 @@ public interface ButtonOption extends Option<Consumer<YACLScreen>> {
class Builder {
private Text name;
private final List<Text> tooltipLines = new ArrayList<>();
+ private boolean available = true;
private Function<ButtonOption, Controller<Consumer<YACLScreen>>> controlGetter;
private Consumer<YACLScreen> action;
@@ -29,6 +33,11 @@ public interface ButtonOption extends Option<Consumer<YACLScreen>> {
}
+ /**
+ * Sets the name to be used by the option.
+ *
+ * @see Option#name()
+ */
public Builder name(@NotNull Text name) {
Validate.notNull(name, "`name` cannot be null");
@@ -36,13 +45,25 @@ public interface ButtonOption extends Option<Consumer<YACLScreen>> {
return this;
}
+ /**
+ * Sets the tooltip to be used by the option.
+ * Can be invoked twice to append more lines.
+ * No need to wrap the text yourself, the gui does this itself.
+ *
+ * @param tooltips text lines - merged with a new-line on {@link Option.Builder#build()}.
+ */
public Builder tooltip(@NotNull Text... tooltips) {
- Validate.notEmpty(tooltips, "`tooltips` cannot be empty");
+ Validate.notNull(tooltips, "`tooltips` cannot be empty");
tooltipLines.addAll(List.of(tooltips));
return this;
}
+ /**
+ * Action to be executed upon button press
+ *
+ * @see ButtonOption#action()
+ */
public Builder action(@NotNull Consumer<YACLScreen> action) {
Validate.notNull(action, "`action` cannot be null");
@@ -50,6 +71,22 @@ public interface ButtonOption extends Option<Consumer<YACLScreen>> {
return this;
}
+ /**
+ * Sets if the option can be configured
+ *
+ * @see Option#available()
+ */
+ public Builder available(boolean available) {
+ this.available = available;
+ return this;
+ }
+
+ /**
+ * Sets the controller for the option.
+ * This is how you interact and change the options.
+ *
+ * @see dev.isxander.yacl.gui.controllers
+ */
public Builder controller(@NotNull Function<ButtonOption, Controller<Consumer<YACLScreen>>> control) {
Validate.notNull(control, "`control` cannot be null");
@@ -71,7 +108,7 @@ public interface ButtonOption extends Option<Consumer<YACLScreen>> {
concatenatedTooltip.append(line);
}
- return new ButtonOptionImpl(name, concatenatedTooltip, action, controlGetter);
+ return new ButtonOptionImpl(name, concatenatedTooltip, action, available, controlGetter);
}
}
}
diff --git a/src/main/java/dev/isxander/yacl/api/Option.java b/src/main/java/dev/isxander/yacl/api/Option.java
index 10f2d10..ff72c4c 100644
--- a/src/main/java/dev/isxander/yacl/api/Option.java
+++ b/src/main/java/dev/isxander/yacl/api/Option.java
@@ -41,6 +41,11 @@ public interface Option<T> {
@NotNull Binding<T> binding();
/**
+ * If the option can be configured
+ */
+ boolean available();
+
+ /**
* Class of the option type.
* Used by some controllers.
*/
@@ -109,6 +114,8 @@ public interface Option<T> {
private Binding<T> binding;
+ private boolean available = true;
+
private final Set<OptionFlag> flags = new HashSet<>();
private final Class<T> typeClass;
@@ -188,6 +195,16 @@ public interface Option<T> {
}
/**
+ * Sets if the option can be configured
+ *
+ * @see Option#available()
+ */
+ public Builder<T> available(boolean available) {
+ this.available = available;
+ return this;
+ }
+
+ /**
* Adds a flag to the option.
* Upon applying changes, all flags are executed.
* {@link Option#flags()}
@@ -236,7 +253,7 @@ public interface Option<T> {
concatenatedTooltip.append(line);
}
- return new OptionImpl<>(name, concatenatedTooltip, controlGetter, binding, ImmutableSet.copyOf(flags), typeClass);
+ return new OptionImpl<>(name, concatenatedTooltip, controlGetter, binding, available, ImmutableSet.copyOf(flags), typeClass);
}
}
}
diff --git a/src/main/java/dev/isxander/yacl/gui/AbstractWidget.java b/src/main/java/dev/isxander/yacl/gui/AbstractWidget.java
index f81cc99..f0f43d3 100644
--- a/src/main/java/dev/isxander/yacl/gui/AbstractWidget.java
+++ b/src/main/java/dev/isxander/yacl/gui/AbstractWidget.java
@@ -12,13 +12,15 @@ import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.sound.PositionedSoundInstance;
-import net.minecraft.client.sound.SoundManager;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.sound.SoundEvents;
+import java.awt.*;
+
public abstract class AbstractWidget implements Element, Drawable, Selectable {
protected final MinecraftClient client = MinecraftClient.getInstance();
protected final TextRenderer textRenderer = client.textRenderer;
+ protected final int inactiveColor = 0xFFA0A0A0;
protected Dimension<Integer> dim;
@@ -56,7 +58,7 @@ public abstract class AbstractWidget implements Element, Drawable, Selectable {
}
- protected void drawButtonRect(MatrixStack matrices, int x1, int y1, int x2, int y2, boolean hovered) {
+ protected void drawButtonRect(MatrixStack matrices, int x1, int y1, int x2, int y2, boolean hovered, boolean enabled) {
if (x1 > x2) {
int xx1 = x1;
x1 = x2;
@@ -73,7 +75,7 @@ public abstract class AbstractWidget implements Element, Drawable, Selectable {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderTexture(0, ClickableWidget.WIDGETS_TEXTURE);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
- int i = hovered ? 2 : 1;
+ int i = !enabled ? 0 : hovered ? 2 : 1;
RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();
RenderSystem.enableDepthTest();
@@ -81,6 +83,15 @@ public abstract class AbstractWidget implements Element, Drawable, Selectable {
DrawableHelper.drawTexture(matrices, x1 + width / 2, y1, 0, 200 - width / 2f, 46 + i * 20, width / 2, height, 256, 256);
}
+ 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),
+ color.getAlpha()).getRGB();
+ }
+
public void playDownSound() {
MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F));
}
diff --git a/src/main/java/dev/isxander/yacl/gui/CategoryListWidget.java b/src/main/java/dev/isxander/yacl/gui/CategoryListWidget.java
index 9291329..fa1e0f9 100644
--- a/src/main/java/dev/isxander/yacl/gui/CategoryListWidget.java
+++ b/src/main/java/dev/isxander/yacl/gui/CategoryListWidget.java
@@ -33,6 +33,12 @@ public class CategoryListWidget extends ElementListWidget<CategoryListWidget.Cat
RenderSystem.disableScissor();
}
+ public void postRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {
+ for (CategoryEntry entry : children()) {
+ entry.postRender(matrices, mouseX, mouseY, delta);
+ }
+ }
+
@Override
public int getRowWidth() {
return width - width / 10;
@@ -73,6 +79,10 @@ public class CategoryListWidget extends ElementListWidget<CategoryListWidget.Cat
categoryButton.render(matrices, mouseX, mouseY, tickDelta);
}
+ private void postRender(MatrixStack matrices, int mouseX, int mouseY, float tickDelta) {
+ categoryButton.renderHoveredTooltip(matrices, mouseX, mouseY);
+ }
+
@Override
public List<? extends Element> children() {
return ImmutableList.of(categoryButton);
diff --git a/src/main/java/dev/isxander/yacl/gui/OptionListWidget.java b/src/main/java/dev/isxander/yacl/gui/OptionListWidget.java
index 466c44c..0c9baf5 100644
--- a/src/main/java/dev/isxander/yacl/gui/OptionListWidget.java
+++ b/src/main/java/dev/isxander/yacl/gui/OptionListWidget.java
@@ -140,9 +140,7 @@ public class OptionListWidget extends ElementListWidget<OptionListWidget.Entry>
}
}
- @Override
- public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
- super.render(matrices, mouseX, mouseY, delta);
+ public void postRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {
for (Entry entry : children()) {
entry.postRender(matrices, mouseX, mouseY, delta);
}
diff --git a/src/main/java/dev/isxander/yacl/gui/TooltipButtonWidget.java b/src/main/java/dev/isxander/yacl/gui/TooltipButtonWidget.java
index 3131c97..0f34e61 100644
--- a/src/main/java/dev/isxander/yacl/gui/TooltipButtonWidget.java
+++ b/src/main/java/dev/isxander/yacl/gui/TooltipButtonWidget.java
@@ -2,6 +2,7 @@ package dev.isxander.yacl.gui;
import dev.isxander.yacl.impl.YACLConstants;
import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.font.MultilineText;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.util.math.MatrixStack;
@@ -15,7 +16,7 @@ public class TooltipButtonWidget extends ButtonWidget {
protected int prevMouseX, prevMouseY;
protected final Screen screen;
- protected List<OrderedText> wrappedDescription;
+ 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);
@@ -37,13 +38,13 @@ public class TooltipButtonWidget extends ButtonWidget {
prevMouseY = mouseY;
}
- public void renderTooltip(MatrixStack matrices, int mouseX, int mouseY) {
+ public void renderHoveredTooltip(MatrixStack matrices, int mouseX, int mouseY) {
if (hoveredTicks >= YACLConstants.HOVER_TICKS) {
- screen.renderOrderedTooltip(matrices, wrappedDescription, mouseX, mouseY);
+ YACLScreen.renderMultilineTooltip(matrices, MinecraftClient.getInstance().textRenderer, wrappedDescription, mouseX, mouseY, screen.width, screen.height);
}
}
public void setTooltip(Text tooltip) {
- wrappedDescription = MinecraftClient.getInstance().textRenderer.wrapLines(tooltip, screen.width / 2);
+ wrappedDescription = MultilineText.create(MinecraftClient.getInstance().textRenderer, tooltip, screen.width / 2);
}
}
diff --git a/src/main/java/dev/isxander/yacl/gui/YACLScreen.java b/src/main/java/dev/isxander/yacl/gui/YACLScreen.java
index 53fa2bf..3fb1ad5 100644
--- a/src/main/java/dev/isxander/yacl/gui/YACLScreen.java
+++ b/src/main/java/dev/isxander/yacl/gui/YACLScreen.java
@@ -1,5 +1,6 @@
package dev.isxander.yacl.gui;
+import com.mojang.blaze3d.systems.RenderSystem;
import dev.isxander.yacl.api.ConfigCategory;
import dev.isxander.yacl.api.Option;
import dev.isxander.yacl.api.OptionFlag;
@@ -7,11 +8,16 @@ import dev.isxander.yacl.api.YetAnotherConfigLib;
import dev.isxander.yacl.api.utils.Dimension;
import dev.isxander.yacl.api.utils.OptionUtils;
import dev.isxander.yacl.impl.YACLConstants;
+import net.minecraft.client.font.MultilineText;
+import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.tooltip.TooltipComponent;
+import net.minecraft.client.render.*;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
+import net.minecraft.util.math.Matrix4f;
import java.util.ArrayList;
import java.util.HashSet;
@@ -130,12 +136,14 @@ public class YACLScreen extends Screen {
super.render(matrices, mouseX, mouseY, delta);
categoryList.render(matrices, mouseX, mouseY, delta);
searchFieldWidget.render(matrices, mouseX, mouseY, delta);
-
optionList.render(matrices, mouseX, mouseY, delta);
+ categoryList.postRender(matrices, mouseX, mouseY, delta);
+ optionList.postRender(matrices, mouseX, mouseY, delta);
+
for (Element child : children()) {
if (child instanceof TooltipButtonWidget tooltipButtonWidget) {
- tooltipButtonWidget.renderTooltip(matrices, mouseX, mouseY);
+ tooltipButtonWidget.renderHoveredTooltip(matrices, mouseX, mouseY);
}
}
}
@@ -232,4 +240,50 @@ public class YACLScreen extends Screen {
public void close() {
client.setScreen(parent);
}
+
+ public static void renderMultilineTooltip(MatrixStack matrices, TextRenderer textRenderer, MultilineText text, int x, int y, int screenWidth, int screenHeight) {
+ if (text.count() > 0) {
+ int maxWidth = text.getMaxWidth();
+ int lineHeight = textRenderer.fontHeight + 1;
+ int height = text.count() * lineHeight;
+
+ int drawX = x + 12;
+ int drawY = y - 12;
+ if (drawX + maxWidth > screenWidth) {
+ drawX -= 28 + maxWidth;
+ }
+
+ if (drawY + height + 6 > screenHeight) {
+ drawY = screenHeight - height - 6;
+ }
+
+ matrices.push();
+ Tessellator tessellator = Tessellator.getInstance();
+ BufferBuilder bufferBuilder = tessellator.getBuffer();
+ RenderSystem.setShader(GameRenderer::getPositionColorShader);
+ 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);
+ RenderSystem.enableDepthTest();
+ RenderSystem.disableTexture();
+ RenderSystem.enableBlend();
+ RenderSystem.defaultBlendFunc();
+ BufferRenderer.drawWithShader(bufferBuilder.end());
+ RenderSystem.disableBlend();
+ RenderSystem.enableTexture();
+ matrices.translate(0.0, 0.0, 400.0);
+
+ text.drawWithShadow(matrices, drawX, drawY, lineHeight, -1);
+
+ matrices.pop();
+ }
+ }
}
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/ActionController.java b/src/main/java/dev/isxander/yacl/gui/controllers/ActionController.java
index e337ee3..3550072 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/ActionController.java
+++ b/src/main/java/dev/isxander/yacl/gui/controllers/ActionController.java
@@ -80,7 +80,7 @@ public class ActionController implements Controller<Consumer<YACLScreen>> {
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
- if (isMouseOver(mouseX, mouseY)) {
+ if (isMouseOver(mouseX, mouseY) && isAvailable()) {
executeAction();
return true;
}
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/BooleanController.java b/src/main/java/dev/isxander/yacl/gui/controllers/BooleanController.java
index 38be6db..bb5304b 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/BooleanController.java
+++ b/src/main/java/dev/isxander/yacl/gui/controllers/BooleanController.java
@@ -115,7 +115,7 @@ public class BooleanController implements Controller<Boolean> {
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
- if (!isMouseOver(mouseX, mouseY))
+ if (!isMouseOver(mouseX, mouseY) || !isAvailable())
return false;
toggleSetting();
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java b/src/main/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java
index 54c426d..1c986e4 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java
+++ b/src/main/java/dev/isxander/yacl/gui/controllers/ControllerWidget.java
@@ -5,6 +5,7 @@ import dev.isxander.yacl.api.utils.Dimension;
import dev.isxander.yacl.gui.AbstractWidget;
import dev.isxander.yacl.gui.YACLScreen;
import dev.isxander.yacl.impl.YACLConstants;
+import net.minecraft.client.font.MultilineText;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
import net.minecraft.client.util.math.MatrixStack;
@@ -15,7 +16,7 @@ import java.util.List;
public abstract class ControllerWidget<T extends Controller<?>> extends AbstractWidget {
protected final T control;
- protected final List<OrderedText> wrappedTooltip;
+ protected final MultilineText wrappedTooltip;
protected final YACLScreen screen;
protected boolean focused = false;
@@ -28,7 +29,7 @@ public abstract class ControllerWidget<T extends Controller<?>> extends Abstract
super(dim);
this.control = control;
this.screen = screen;
- this.wrappedTooltip = textRenderer.wrapLines(control.option().tooltip(), screen.width / 2);
+ this.wrappedTooltip = MultilineText.create(textRenderer, control.option().tooltip(), screen.width / 2);
}
@Override
@@ -53,10 +54,10 @@ public abstract class ControllerWidget<T extends Controller<?>> extends Abstract
Text shortenedName = Text.literal(nameString).fillStyle(name.getStyle());
- drawButtonRect(matrices, dim.x(), dim.y(), dim.xLimit(), dim.yLimit(), isHovered());
+ drawButtonRect(matrices, dim.x(), dim.y(), dim.xLimit(), dim.yLimit(), isHovered(), isAvailable());
matrices.push();
matrices.translate(dim.x() + getXPadding(), getTextY(), 0);
- textRenderer.drawWithShadow(matrices, shortenedName, 0, 0, -1);
+ textRenderer.drawWithShadow(matrices, shortenedName, 0, 0, getValueColor());
matrices.pop();
drawValueText(matrices, mouseX, mouseY, delta);
@@ -71,7 +72,7 @@ public abstract class ControllerWidget<T extends Controller<?>> extends Abstract
@Override
public void postRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {
if (hoveredTicks > YACLConstants.HOVER_TICKS) {
- screen.renderOrderedTooltip(matrices, wrappedTooltip, mouseX, mouseY);
+ YACLScreen.renderMultilineTooltip(matrices, textRenderer, wrappedTooltip, mouseX, mouseY, screen.width, screen.height);
}
}
@@ -83,7 +84,7 @@ public abstract class ControllerWidget<T extends Controller<?>> extends Abstract
Text valueText = getValueText();
matrices.push();
matrices.translate(dim.xLimit() - textRenderer.getWidth(valueText) - getXPadding(), getTextY(), 0);
- textRenderer.drawWithShadow(matrices, valueText, 0, 0, -1);
+ textRenderer.drawWithShadow(matrices, valueText, 0, 0, getValueColor());
matrices.pop();
}
@@ -98,7 +99,7 @@ public abstract class ControllerWidget<T extends Controller<?>> extends Abstract
}
public boolean isHovered() {
- return hovered || focused;
+ return isAvailable() && (hovered || focused);
}
protected abstract int getHoveredControlWidth();
@@ -119,6 +120,14 @@ public abstract class ControllerWidget<T extends Controller<?>> extends Abstract
return control.formatValue();
}
+ protected boolean isAvailable() {
+ return control.option().available();
+ }
+
+ protected int getValueColor() {
+ return isAvailable() ? -1 : inactiveColor;
+ }
+
protected void drawOutline(MatrixStack matrices, int x1, int y1, int x2, int y2, int width, int color) {
DrawableHelper.fill(matrices, x1, y1, x2, y1 + width, color);
DrawableHelper.fill(matrices, x2, y1, x2 - width, y2, color);
@@ -132,6 +141,9 @@ public abstract class ControllerWidget<T extends Controller<?>> extends Abstract
@Override
public boolean changeFocus(boolean lookForwards) {
+ if (!isAvailable())
+ return false;
+
this.focused = !this.focused;
return this.focused;
}
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/EnumController.java b/src/main/java/dev/isxander/yacl/gui/controllers/EnumController.java
index 9d8e59c..261c067 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/EnumController.java
+++ b/src/main/java/dev/isxander/yacl/gui/controllers/EnumController.java
@@ -98,7 +98,7 @@ public class EnumController<T extends Enum<T>> implements Controller<T> {
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
- if (!isMouseOver(mouseX, mouseY) || (button != 0 && button != 1))
+ if (!isMouseOver(mouseX, mouseY) || (button != 0 && button != 1) || !isAvailable())
return false;
playDownSound();
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/LabelController.java b/src/main/java/dev/isxander/yacl/gui/controllers/LabelController.java
index 33ca176..57927f5 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/LabelController.java
+++ b/src/main/java/dev/isxander/yacl/gui/controllers/LabelController.java
@@ -57,7 +57,7 @@ public class LabelController implements Controller<Text> {
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
updateText();
- wrappedText.drawWithShadow(matrices, dim.x(), dim.y() + getYPadding(), textRenderer.fontHeight, -1);
+ wrappedText.drawWithShadow(matrices, dim.x(), dim.y() + getYPadding(), textRenderer.fontHeight, option().available() ? -1 : 0xFFA0A0A0);
}
private int getYPadding() {
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/TickBoxController.java b/src/main/java/dev/isxander/yacl/gui/controllers/TickBoxController.java
index df0ae83..d7864e0 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/TickBoxController.java
+++ b/src/main/java/dev/isxander/yacl/gui/controllers/TickBoxController.java
@@ -63,23 +63,27 @@ public class TickBoxController implements Controller<Boolean> {
int outlineY1 = dim.centerY() - outlineSize / 2;
int outlineX2 = dim.xLimit() - getXPadding();
int outlineY2 = dim.centerY() + outlineSize / 2;
- drawOutline(matrices, outlineX1 + 1, outlineY1 + 1, outlineX2 + 1, outlineY2 + 1, 1, 0xFF404040);
- drawOutline(matrices, outlineX1, outlineY1, outlineX2, outlineY2, 1, -1);
+
+ int color = getValueColor();
+ int shadowColor = multiplyColor(color, 0.25f);
+
+ drawOutline(matrices, outlineX1 + 1, outlineY1 + 1, outlineX2 + 1, outlineY2 + 1, 1, shadowColor);
+ drawOutline(matrices, outlineX1, outlineY1, outlineX2, outlineY2, 1, color);
if (control.option().pendingValue()) {
- DrawableHelper.fill(matrices, outlineX1 + 3, outlineY1 + 3, outlineX2 - 1, outlineY2 - 1, 0xFF404040);
- DrawableHelper.fill(matrices, outlineX1 + 2, outlineY1 + 2, outlineX2 - 2, outlineY2 - 2, -1);
+ DrawableHelper.fill(matrices, outlineX1 + 3, outlineY1 + 3, outlineX2 - 1, outlineY2 - 1, shadowColor);
+ DrawableHelper.fill(matrices, outlineX1 + 2, outlineY1 + 2, outlineX2 - 2, outlineY2 - 2, color);
}
}
@Override
protected void drawValueText(MatrixStack matrices, int mouseX, int mouseY, float delta) {
- if (!hovered)
+ if (!isHovered())
drawHoveredControl(matrices, mouseX, mouseY, delta);
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
- if (!isMouseOver(mouseX, mouseY))
+ if (!isMouseOver(mouseX, mouseY) || !isAvailable())
return false;
toggleSetting();
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/slider/SliderControllerElement.java b/src/main/java/dev/isxander/yacl/gui/controllers/slider/SliderControllerElement.java
index fa763b7..d07377a 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/slider/SliderControllerElement.java
+++ b/src/main/java/dev/isxander/yacl/gui/controllers/slider/SliderControllerElement.java
@@ -51,7 +51,7 @@ public class SliderControllerElement extends ControllerWidget<ISliderController<
@Override
protected void drawValueText(MatrixStack matrices, int mouseX, int mouseY, float delta) {
matrices.push();
- if (hovered || focused)
+ if (isHovered())
matrices.translate(-(sliderBounds.width() + 6 + getThumbWidth() / 2f), 0, 0);
super.drawValueText(matrices, mouseX, mouseY, delta);
matrices.pop();
@@ -59,7 +59,7 @@ public class SliderControllerElement extends ControllerWidget<ISliderController<
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
- if (button != 0 || !sliderBounds.isPointInside((int) mouseX, (int) mouseY))
+ if (!isAvailable() || button != 0 || !sliderBounds.isPointInside((int) mouseX, (int) mouseY))
return false;
mouseDown = true;
@@ -70,7 +70,7 @@ public class SliderControllerElement extends ControllerWidget<ISliderController<
@Override
public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
- if (button != 0 || !mouseDown)
+ if (!isAvailable() || button != 0 || !mouseDown)
return false;
setValueFromMouse(mouseX);
@@ -84,7 +84,7 @@ public class SliderControllerElement extends ControllerWidget<ISliderController<
@Override
public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
- if ((!isMouseOver(mouseX, mouseY)) || (!Screen.hasShiftDown() && !Screen.hasControlDown()))
+ if (!isAvailable() || (!isMouseOver(mouseX, mouseY)) || (!Screen.hasShiftDown() && !Screen.hasControlDown()))
return false;
incrementValue(amount);
@@ -93,7 +93,7 @@ public class SliderControllerElement extends ControllerWidget<ISliderController<
@Override
public boolean mouseReleased(double mouseX, double mouseY, int button) {
- if (mouseDown)
+ if (isAvailable() && mouseDown)
playDownSound();
mouseDown = false;
diff --git a/src/main/java/dev/isxander/yacl/gui/controllers/string/StringControllerElement.java b/src/main/java/dev/isxander/yacl/gui/controllers/string/StringControllerElement.java
index c606d69..8598172 100644
--- a/src/main/java/dev/isxander/yacl/gui/controllers/string/StringControllerElement.java
+++ b/src/main/java/dev/isxander/yacl/gui/controllers/string/StringControllerElement.java
@@ -56,7 +56,7 @@ public class StringControllerElement extends ControllerWidget<IStringController<
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
- if (inputFieldBounds.isPointInside((int) mouseX, (int) mouseY)) {
+ if (isAvailable() && inputFieldBounds.isPointInside((int) mouseX, (int) mouseY)) {
if (!inputFieldFocused) {
inputFieldFocused = true;
caretPos = getDefaultCarotPos();
diff --git a/src/main/java/dev/isxander/yacl/impl/ButtonOptionImpl.java b/src/main/java/dev/isxander/yacl/impl/ButtonOptionImpl.java
index 2cdc8a6..a600bc3 100644
--- a/src/main/java/dev/isxander/yacl/impl/ButtonOptionImpl.java
+++ b/src/main/java/dev/isxander/yacl/impl/ButtonOptionImpl.java
@@ -19,6 +19,7 @@ public class ButtonOptionImpl implements ButtonOption {
private final Text name;
private final Text tooltip;
private final Consumer<YACLScreen> action;
+ private final boolean available;
private final Controller<Consumer<YACLScreen>> controller;
private final Binding<Consumer<YACLScreen>> binding;
@@ -26,11 +27,13 @@ public class ButtonOptionImpl implements ButtonOption {
@NotNull Text name,
@Nullable Text tooltip,
@NotNull Consumer<YACLScreen> action,
+ boolean available,
@NotNull Function<ButtonOption, Controller<Consumer<YACLScreen>>> controlGetter
) {
this.name = name;
this.tooltip = tooltip;
this.action = action;
+ this.available = available;
this.controller = controlGetter.apply(this);
this.binding = new EmptyBinderImpl();
}
@@ -51,6 +54,11 @@ public class ButtonOptionImpl implements ButtonOption {
}
@Override
+ public boolean available() {
+ return available;
+ }
+
+ @Override
public @NotNull Controller<Consumer<YACLScreen>> controller() {
return controller;
}
diff --git a/src/main/java/dev/isxander/yacl/impl/OptionImpl.java b/src/main/java/dev/isxander/yacl/impl/OptionImpl.java
index 445420e..5a31a70 100644
--- a/src/main/java/dev/isxander/yacl/impl/OptionImpl.java
+++ b/src/main/java/dev/isxander/yacl/impl/OptionImpl.java
@@ -18,6 +18,7 @@ public class OptionImpl<T> implements Option<T> {
private final Text tooltip;
private final Controller<T> controller;
private final Binding<T> binding;
+ private final boolean available;
private final ImmutableSet<OptionFlag> flags;
@@ -30,6 +31,7 @@ public class OptionImpl<T> implements Option<T> {
@Nullable Text tooltip,
@NotNull Function<Option<T>, Controller<T>> controlGetter,
@NotNull Binding<T> binding,
+ boolean available,
ImmutableSet<OptionFlag> flags,
@NotNull Class<T> typeClass
) {
@@ -37,6 +39,7 @@ public class OptionImpl<T> implements Option<T> {
this.tooltip = tooltip;
this.controller = controlGetter.apply(this);
this.binding = binding;
+ this.available = available;
this.flags = flags;
this.typeClass = typeClass;
this.pendingValue = binding().getValue();
@@ -63,6 +66,11 @@ public class OptionImpl<T> implements Option<T> {
}
@Override
+ public boolean available() {
+ return available;
+ }
+
+ @Override
public @NotNull Class<T> typeClass() {
return typeClass;
}
diff --git a/src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java b/src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java
index d1ef4d0..df81768 100644
--- a/src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java
+++ b/src/testmod/java/dev/isxander/yacl/test/ModMenuIntegration.java
@@ -39,6 +39,11 @@ public class ModMenuIntegration implements ModMenuApi {
.controller(ActionController::new)
.action(screen -> MinecraftClient.getInstance().setScreen(getWikiGroups(screen)))
.build())
+ .option(ButtonOption.createBuilder()
+ .name(Text.of("Unavailable Test Suite"))
+ .controller(ActionController::new)
+ .action(screen -> MinecraftClient.getInstance().setScreen(getDisabledTest(screen)))
+ .build())
.build())
.build().generateScreen(parent);
}
@@ -311,6 +316,38 @@ public class ModMenuIntegration implements ModMenuApi {
.build().generateScreen(parent);
}
+ private Screen getDisabledTest(Screen parent) {
+ return YetAnotherConfigLib.createBuilder()
+ .title(Text.empty())
+ .category(ConfigCategory.createBuilder()
+ .name(Text.of("Disabled Test"))
+ .option(Option.createBuilder(int.class)
+ .name(Text.of("Slider"))
+ .binding(Binding.immutable(0))
+ .controller(opt -> new IntegerSliderController(opt, 0, 5, 1))
+ .available(false)
+ .build())
+ .option(Option.createBuilder(boolean.class)
+ .name(Text.of("Tick Box"))
+ .binding(Binding.immutable(true))
+ .controller(TickBoxController::new)
+ .available(false)
+ .build())
+ .option(Option.createBuilder(boolean.class)
+ .name(Text.of("Tick Box (Enabled)"))
+ .binding(Binding.immutable(true))
+ .controller(TickBoxController::new)
+ .build())
+ .option(Option.createBuilder(String.class)
+ .name(Text.of("Text Field"))
+ .binding(Binding.immutable("hi"))
+ .controller(StringController::new)
+ .available(false)
+ .build())
+ .build())
+ .build().generateScreen(parent);
+ }
+
private Screen getWikiBasic(Screen parent) {
return YetAnotherConfigLib.createBuilder()
.title(Text.of("Mod Name"))