diff --git a/src/main/java/org/betterx/bclib/client/gui/modmenu/TestScreen.java b/src/main/java/org/betterx/bclib/client/gui/modmenu/TestScreen.java index 1b165e40..d4a9af9d 100644 --- a/src/main/java/org/betterx/bclib/client/gui/modmenu/TestScreen.java +++ b/src/main/java/org/betterx/bclib/client/gui/modmenu/TestScreen.java @@ -1,9 +1,6 @@ package org.betterx.bclib.client.gui.modmenu; -import org.betterx.ui.layout.components.Button; -import org.betterx.ui.layout.components.HorizontalStack; -import org.betterx.ui.layout.components.Panel; -import org.betterx.ui.layout.components.VerticalStack; +import org.betterx.ui.layout.components.*; import org.betterx.ui.layout.values.DynamicSize; import com.mojang.blaze3d.vertex.PoseStack; @@ -27,15 +24,22 @@ public class TestScreen extends Screen { main = new Panel(this.width, this.height); HorizontalStack columns = new HorizontalStack<>(DynamicSize.relative(1), DynamicSize.relative(1)); VerticalStack rows = new VerticalStack<>(DynamicSize.fit(), DynamicSize.relative(1)); -// columns.add(new Empty(DynamicSize.fill(), DynamicSize.fill())); -// columns.add(rows); -// columns.add(new Empty(DynamicSize.fill(), DynamicSize.fill())); rows.addFiller(); + rows.add(new Range( + DynamicSize.fill(), DynamicSize.fit(), + Component.literal("Integer"), + 10, 90, 20, + (slider, value) -> { + System.out.println(value); + } + )); + rows.addSpacer(8); rows.add(new Button( DynamicSize.fit(), DynamicSize.fit(), Component.literal("test"), (bt) -> { + System.out.println("clicked test"); }, (bt, pose, x, y) -> { } @@ -46,6 +50,7 @@ public class TestScreen extends Screen { DynamicSize.fit(), DynamicSize.fit(), Component.literal("Hello World"), (bt) -> { + System.out.println("clicked hello"); }, (bt, pose, x, y) -> { } diff --git a/src/main/java/org/betterx/ui/layout/components/Range.java b/src/main/java/org/betterx/ui/layout/components/Range.java new file mode 100644 index 00000000..143cc55b --- /dev/null +++ b/src/main/java/org/betterx/ui/layout/components/Range.java @@ -0,0 +1,82 @@ +package org.betterx.ui.layout.components; + +import org.betterx.ui.layout.components.render.RangeRenderer; +import org.betterx.ui.layout.values.DynamicSize; +import org.betterx.ui.vanilla.Slider; + +import net.minecraft.network.chat.Component; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public class Range extends AbstractVanillaComponent, Range> { + private final Slider.SliderValueChanged onChange; + private final N minValue; + private final N maxValue; + private final N initialValue; + + public Range( + DynamicSize width, + DynamicSize height, + Component component, + N minValue, + N maxValue, + N initialValue, + Slider.SliderValueChanged onChange + ) { + super(width, height, new RangeRenderer<>(), component); + this.onChange = onChange; + this.minValue = minValue; + this.maxValue = maxValue; + this.initialValue = initialValue; + } + + public Range( + DynamicSize width, + DynamicSize height, + N minValue, + N maxValue, + N initialValue, + Slider.SliderValueChanged onChange + ) { + super(width, height, new RangeRenderer<>(), null); + this.onChange = onChange; + this.minValue = minValue; + this.maxValue = maxValue; + this.initialValue = initialValue; + } + + @Override + protected Slider createVanillaComponent() { + return new Slider<>( + 0, + 0, + relativeBounds.width, + relativeBounds.height, + component, + minValue, + maxValue, + initialValue, + onChange + ); + } + + + @Override + protected Component contentComponent() { + Slider dummy = new Slider<>( + 0, + 0, + 100, + 20, + component, + minValue, + maxValue, + initialValue, + (a, b) -> { + } + ); + return dummy.getValueComponent(maxValue); + } +} diff --git a/src/main/java/org/betterx/ui/layout/components/render/RangeRenderer.java b/src/main/java/org/betterx/ui/layout/components/render/RangeRenderer.java new file mode 100644 index 00000000..ca8d36c4 --- /dev/null +++ b/src/main/java/org/betterx/ui/layout/components/render/RangeRenderer.java @@ -0,0 +1,13 @@ +package org.betterx.ui.layout.components.render; + +import org.betterx.ui.layout.components.AbstractVanillaComponentRenderer; +import org.betterx.ui.layout.components.Range; +import org.betterx.ui.vanilla.Slider; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public class RangeRenderer extends AbstractVanillaComponentRenderer, Range> { + +} diff --git a/src/main/java/org/betterx/ui/vanilla/Slider.java b/src/main/java/org/betterx/ui/vanilla/Slider.java new file mode 100644 index 00000000..94537dd9 --- /dev/null +++ b/src/main/java/org/betterx/ui/vanilla/Slider.java @@ -0,0 +1,103 @@ +package org.betterx.ui.vanilla; + +import net.minecraft.client.gui.components.AbstractSliderButton; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.Component; + +public class Slider extends AbstractSliderButton { + @FunctionalInterface + public interface SliderValueChanged { + void now(Slider slider, N newValue); + } + + protected final Component title; + protected final N minValue; + protected final N maxValue; + + protected final SliderValueChanged onChange; + + public Slider( + int x, + int y, + int width, + int height, + N minValue, + N maxValue, + N initialValue, + SliderValueChanged onChange + ) { + this(x, y, width, height, null, minValue, maxValue, initialValue, onChange); + } + + public Slider( + int x, + int y, + int width, + int height, + Component title, + N minValue, + N maxValue, + N initialValue, + SliderValueChanged onChange + ) { + super( + x, + y, + width, + height, + CommonComponents.EMPTY, + (initialValue.doubleValue() - minValue.doubleValue()) / (maxValue.doubleValue() - minValue.doubleValue()) + ); + this.title = title; + this.minValue = minValue; + this.maxValue = maxValue; + this.onChange = onChange; + + this.updateMessage(); + } + + protected N currentValue() { + Double res = value * (maxValue.doubleValue() - minValue.doubleValue()) + minValue.doubleValue(); + if (minValue instanceof Integer) { + return (N) (Integer) res.intValue(); + } + if (minValue instanceof Byte) { + return (N) (Byte) res.byteValue(); + } + if (minValue instanceof Short) { + return (N) (Short) res.shortValue(); + } + if (minValue instanceof Long) { + return (N) (Long) res.longValue(); + } + if (minValue instanceof Float) { + return (N) (Float) res.floatValue(); + } + if (minValue instanceof Double) { + return (N) res; + } + throw new IllegalStateException("The Type " + minValue.getClass() + .getSimpleName() + " is not nativley supported. Please override currentValue with an implementation ofr that type"); + } + + protected String valueToString(N value) { + return "" + value; + } + + public Component getValueComponent(N value) { + return Component.literal("" + this.valueToString(value)); + } + + @Override + protected void updateMessage() { + final Component valueComponent = getValueComponent(this.currentValue()); + this.setMessage(title == null ? valueComponent : title.copy() + .append(": ") + .append(valueComponent)); + } + + @Override + protected void applyValue() { + onChange.now(this, currentValue()); + } +}