OptionInstance.java
net.minecraft.client.OptionInstance
信息
- 全限定名:net.minecraft.client.OptionInstance
- 类型:public final class
- 包:net.minecraft.client
- 源码路径:src/main/java/net/minecraft/client/OptionInstance.java
- 起始行号:L38
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L39 - 说明:
TODO
- 类型:
-
BOOLEAN_VALUES- 类型:
OptionInstance.Enum<Boolean> - 修饰符:
public static final - 源码定位:
L40 - 说明:
TODO
- 类型:
-
BOOLEAN_TO_STRING- 类型:
OptionInstance.CaptionBasedToString<Boolean> - 修饰符:
public static final - 源码定位:
L41 - 说明:
TODO
- 类型:
-
tooltip- 类型:
OptionInstance.TooltipSupplier<T> - 修饰符:
private final - 源码定位:
L44 - 说明:
TODO
- 类型:
-
toString- 类型:
Function<T,Component> - 修饰符:
private final - 源码定位:
L45 - 说明:
TODO
- 类型:
-
values- 类型:
OptionInstance.ValueSet<T> - 修饰符:
private final - 源码定位:
L46 - 说明:
TODO
- 类型:
-
codec- 类型:
Codec<T> - 修饰符:
private final - 源码定位:
L47 - 说明:
TODO
- 类型:
-
initialValue- 类型:
T - 修饰符:
private final - 源码定位:
L48 - 说明:
TODO
- 类型:
-
onValueUpdate- 类型:
Consumer<T> - 修饰符:
private final - 源码定位:
L49 - 说明:
TODO
- 类型:
-
caption- 类型:
Component - 修饰符:
private final - 源码定位:
L50 - 说明:
TODO
- 类型:
-
value- 类型:
T - 修饰符:
private - 源码定位:
L51 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.client.OptionInstance.AltEnum- 类型:
record - 修饰符:
public - 源码定位:
L164 - 说明:
TODO
- 类型:
-
net.minecraft.client.OptionInstance.CaptionBasedToString- 类型:
interface - 修饰符:
public - 源码定位:
L179 - 说明:
TODO
- 类型:
-
net.minecraft.client.OptionInstance.ClampingLazyMaxIntRange- 类型:
record - 修饰符:
public - 源码定位:
L184 - 说明:
TODO
- 类型:
-
net.minecraft.client.OptionInstance.CycleableValueSet- 类型:
interface - 修饰符:
package-private - 源码定位:
L221 - 说明:
TODO
- 类型:
-
net.minecraft.client.OptionInstance.CycleableValueSet.ValueSetter- 类型:
interface - 修饰符:
public - 源码定位:
L243 - 说明:
TODO
- 类型:
-
net.minecraft.client.OptionInstance.Enum- 类型:
record - 修饰符:
public - 源码定位:
L249 - 说明:
TODO
- 类型:
-
net.minecraft.client.OptionInstance.IntRange- 类型:
record - 修饰符:
public - 源码定位:
L262 - 说明:
TODO
- 类型:
-
net.minecraft.client.OptionInstance.IntRangeBase- 类型:
interface - 修饰符:
package-private - 源码定位:
L278 - 说明:
TODO
- 类型:
-
net.minecraft.client.OptionInstance.LazyEnum- 类型:
record - 修饰符:
public - 源码定位:
L357 - 说明:
TODO
- 类型:
-
net.minecraft.client.OptionInstance.OptionInstanceSliderButton- 类型:
class - 修饰符:
public static final - 源码定位:
L370 - 说明:
TODO
- 类型:
-
net.minecraft.client.OptionInstance.SliderableEnum- 类型:
record - 修饰符:
public - 源码定位:
L487 - 说明:
TODO
- 类型:
-
net.minecraft.client.OptionInstance.SliderableOrCyclableValueSet- 类型:
interface - 修饰符:
package-private - 源码定位:
L529 - 说明:
TODO
- 类型:
-
net.minecraft.client.OptionInstance.SliderableValueSet- 类型:
interface - 修饰符:
package-private - 源码定位:
L543 - 说明:
TODO
- 类型:
-
net.minecraft.client.OptionInstance.TooltipSupplier- 类型:
interface - 修饰符:
public - 源码定位:
L572 - 说明:
TODO
- 类型:
-
net.minecraft.client.OptionInstance.UnitDouble- 类型:
enum - 修饰符:
public static - 源码定位:
L577 - 说明:
TODO
- 类型:
-
net.minecraft.client.OptionInstance.ValueSet- 类型:
interface - 修饰符:
package-private - 源码定位:
L627 - 说明:
TODO
- 类型:
构造器
public OptionInstance(String captionId, OptionInstance.TooltipSupplier<T> tooltip, OptionInstance.CaptionBasedToString<T> toString, OptionInstance.ValueSet<T> values, T initialValue, Consumer<T> onValueUpdate) @ L81
- 构造器名:OptionInstance
- 源码定位:L81
- 修饰符:public
参数:
- captionId: String
- tooltip: OptionInstance.TooltipSupplier
- toString: OptionInstance.CaptionBasedToString
- values: OptionInstance.ValueSet
- initialValue: T
- onValueUpdate: Consumer
说明:
TODO
public OptionInstance(String captionId, OptionInstance.TooltipSupplier<T> tooltip, OptionInstance.CaptionBasedToString<T> toString, OptionInstance.ValueSet<T> values, Codec<T> codec, T initialValue, Consumer<T> onValueUpdate) @ L92
- 构造器名:OptionInstance
- 源码定位:L92
- 修饰符:public
参数:
- captionId: String
- tooltip: OptionInstance.TooltipSupplier
- toString: OptionInstance.CaptionBasedToString
- values: OptionInstance.ValueSet
- codec: Codec
- initialValue: T
- onValueUpdate: Consumer
说明:
TODO
方法
下面的方法块按源码顺序生成。
public static OptionInstance<Boolean> createBoolean(String captionId, boolean initialValue, Consumer<Boolean> onValueUpdate) @ L53
- 方法名:createBoolean
- 源码定位:L53
- 返回类型:OptionInstance
- 修饰符:public static
参数:
- captionId: String
- initialValue: boolean
- onValueUpdate: Consumer
说明:
TODO
public static OptionInstance<Boolean> createBoolean(String captionId, boolean initialValue) @ L57
- 方法名:createBoolean
- 源码定位:L57
- 返回类型:OptionInstance
- 修饰符:public static
参数:
- captionId: String
- initialValue: boolean
说明:
TODO
public static OptionInstance<Boolean> createBoolean(String captionId, OptionInstance.TooltipSupplier<Boolean> tooltip, boolean initialValue) @ L61
- 方法名:createBoolean
- 源码定位:L61
- 返回类型:OptionInstance
- 修饰符:public static
参数:
- captionId: String
- tooltip: OptionInstance.TooltipSupplier
- initialValue: boolean
说明:
TODO
public static OptionInstance<Boolean> createBoolean(String captionId, OptionInstance.TooltipSupplier<Boolean> tooltip, boolean initialValue, Consumer<Boolean> onValueUpdate) @ L65
- 方法名:createBoolean
- 源码定位:L65
- 返回类型:OptionInstance
- 修饰符:public static
参数:
- captionId: String
- tooltip: OptionInstance.TooltipSupplier
- initialValue: boolean
- onValueUpdate: Consumer
说明:
TODO
public static OptionInstance<Boolean> createBoolean(String captionId, OptionInstance.TooltipSupplier<Boolean> tooltip, OptionInstance.CaptionBasedToString<Boolean> toString, boolean initialValue, Consumer<Boolean> onValueUpdate) @ L71
- 方法名:createBoolean
- 源码定位:L71
- 返回类型:OptionInstance
- 修饰符:public static
参数:
- captionId: String
- tooltip: OptionInstance.TooltipSupplier
- toString: OptionInstance.CaptionBasedToString
- initialValue: boolean
- onValueUpdate: Consumer
说明:
TODO
public static <T> OptionInstance.TooltipSupplier<T> noTooltip() @ L111
- 方法名:noTooltip
- 源码定位:L111
- 返回类型:
OptionInstance.TooltipSupplier - 修饰符:public static
参数:
- 无
说明:
TODO
public static <T> OptionInstance.TooltipSupplier<T> cachedConstantTooltip(Component tooltipComponent) @ L115
- 方法名:cachedConstantTooltip
- 源码定位:L115
- 返回类型:
OptionInstance.TooltipSupplier - 修饰符:public static
参数:
- tooltipComponent: Component
说明:
TODO
public AbstractWidget createButton(Options options) @ L119
- 方法名:createButton
- 源码定位:L119
- 返回类型:AbstractWidget
- 修饰符:public
参数:
- options: Options
说明:
TODO
public AbstractWidget createButton(Options options, int x, int y, int width) @ L123
- 方法名:createButton
- 源码定位:L123
- 返回类型:AbstractWidget
- 修饰符:public
参数:
- options: Options
- x: int
- y: int
- width: int
说明:
TODO
public AbstractWidget createButton(Options options, int x, int y, int width, Consumer<T> onValueChanged) @ L127
- 方法名:createButton
- 源码定位:L127
- 返回类型:AbstractWidget
- 修饰符:public
参数:
- options: Options
- x: int
- y: int
- width: int
- onValueChanged: Consumer
说明:
TODO
public T get() @ L131
- 方法名:get
- 源码定位:L131
- 返回类型:T
- 修饰符:public
参数:
- 无
说明:
TODO
public Codec<T> codec() @ L135
- 方法名:codec
- 源码定位:L135
- 返回类型:Codec
- 修饰符:public
参数:
- 无
说明:
TODO
public String toString() @ L139
- 方法名:toString
- 源码定位:L139
- 返回类型:String
- 修饰符:public
参数:
- 无
说明:
TODO
public void set(T value) @ L144
- 方法名:set
- 源码定位:L144
- 返回类型:void
- 修饰符:public
参数:
- value: T
说明:
TODO
public OptionInstance.ValueSet<T> values() @ L159
- 方法名:values
- 源码定位:L159
- 返回类型:OptionInstance.ValueSet
- 修饰符:public
参数:
- 无
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public final class OptionInstance<T> {
private static final Logger LOGGER = LogUtils.getLogger();
public static final OptionInstance.Enum<Boolean> BOOLEAN_VALUES = new OptionInstance.Enum<>(ImmutableList.of(Boolean.TRUE, Boolean.FALSE), Codec.BOOL);
public static final OptionInstance.CaptionBasedToString<Boolean> BOOLEAN_TO_STRING = (caption, b) -> b
? CommonComponents.OPTION_ON
: CommonComponents.OPTION_OFF;
private final OptionInstance.TooltipSupplier<T> tooltip;
private final Function<T, Component> toString;
private final OptionInstance.ValueSet<T> values;
private final Codec<T> codec;
private final T initialValue;
private final Consumer<T> onValueUpdate;
private final Component caption;
private T value;
public static OptionInstance<Boolean> createBoolean(String captionId, boolean initialValue, Consumer<Boolean> onValueUpdate) {
return createBoolean(captionId, noTooltip(), initialValue, onValueUpdate);
}
public static OptionInstance<Boolean> createBoolean(String captionId, boolean initialValue) {
return createBoolean(captionId, noTooltip(), initialValue, value -> {});
}
public static OptionInstance<Boolean> createBoolean(String captionId, OptionInstance.TooltipSupplier<Boolean> tooltip, boolean initialValue) {
return createBoolean(captionId, tooltip, initialValue, value -> {});
}
public static OptionInstance<Boolean> createBoolean(
String captionId, OptionInstance.TooltipSupplier<Boolean> tooltip, boolean initialValue, Consumer<Boolean> onValueUpdate
) {
return createBoolean(captionId, tooltip, BOOLEAN_TO_STRING, initialValue, onValueUpdate);
}
public static OptionInstance<Boolean> createBoolean(
String captionId,
OptionInstance.TooltipSupplier<Boolean> tooltip,
OptionInstance.CaptionBasedToString<Boolean> toString,
boolean initialValue,
Consumer<Boolean> onValueUpdate
) {
return new OptionInstance<>(captionId, tooltip, toString, BOOLEAN_VALUES, initialValue, onValueUpdate);
}
public OptionInstance(
String captionId,
OptionInstance.TooltipSupplier<T> tooltip,
OptionInstance.CaptionBasedToString<T> toString,
OptionInstance.ValueSet<T> values,
T initialValue,
Consumer<T> onValueUpdate
) {
this(captionId, tooltip, toString, values, values.codec(), initialValue, onValueUpdate);
}
public OptionInstance(
String captionId,
OptionInstance.TooltipSupplier<T> tooltip,
OptionInstance.CaptionBasedToString<T> toString,
OptionInstance.ValueSet<T> values,
Codec<T> codec,
T initialValue,
Consumer<T> onValueUpdate
) {
this.caption = Component.translatable(captionId);
this.tooltip = tooltip;
this.toString = value -> toString.toString(this.caption, value);
this.values = values;
this.codec = codec;
this.initialValue = initialValue;
this.onValueUpdate = onValueUpdate;
this.value = this.initialValue;
}
public static <T> OptionInstance.TooltipSupplier<T> noTooltip() {
return value -> null;
}
public static <T> OptionInstance.TooltipSupplier<T> cachedConstantTooltip(Component tooltipComponent) {
return value -> Tooltip.create(tooltipComponent);
}
public AbstractWidget createButton(Options options) {
return this.createButton(options, 0, 0, 150);
}
public AbstractWidget createButton(Options options, int x, int y, int width) {
return this.createButton(options, x, y, width, value -> {});
}
public AbstractWidget createButton(Options options, int x, int y, int width, Consumer<T> onValueChanged) {
return this.values.createButton(this.tooltip, options, x, y, width, onValueChanged).apply(this);
}
public T get() {
return this.value;
}
public Codec<T> codec() {
return this.codec;
}
@Override
public String toString() {
return this.caption.getString();
}
public void set(T value) {
T newValue = this.values.validateValue(value).orElseGet(() -> {
LOGGER.error("Illegal option value {} for {}", value, this.caption.getString());
return this.initialValue;
});
if (!Minecraft.getInstance().isRunning()) {
this.value = newValue;
} else {
if (!Objects.equals(this.value, newValue)) {
this.value = newValue;
this.onValueUpdate.accept(this.value);
}
}
}
public OptionInstance.ValueSet<T> values() {
return this.values;
}
@OnlyIn(Dist.CLIENT)
public record AltEnum<T>(
List<T> values, List<T> altValues, BooleanSupplier altCondition, OptionInstance.CycleableValueSet.ValueSetter<T> valueSetter, Codec<T> codec
) implements OptionInstance.CycleableValueSet<T> {
@Override
public CycleButton.ValueListSupplier<T> valueListSupplier() {
return CycleButton.ValueListSupplier.create(this.altCondition, this.values, this.altValues);
}
@Override
public Optional<T> validateValue(T value) {
return (this.altCondition.getAsBoolean() ? this.altValues : this.values).contains(value) ? Optional.of(value) : Optional.empty();
}
}
@OnlyIn(Dist.CLIENT)
public interface CaptionBasedToString<T> {
Component toString(final Component caption, final T value);
}
@OnlyIn(Dist.CLIENT)
public record ClampingLazyMaxIntRange(int minInclusive, IntSupplier maxSupplier, int encodableMaxInclusive)
implements OptionInstance.IntRangeBase,
OptionInstance.SliderableOrCyclableValueSet<Integer> {
public Optional<Integer> validateValue(Integer value) {
return Optional.of(Mth.clamp(value, this.minInclusive(), this.maxInclusive()));
}
@Override
public int maxInclusive() {
return this.maxSupplier.getAsInt();
}
@Override
public Codec<Integer> codec() {
return Codec.INT
.validate(
value -> {
int maxExclusive = this.encodableMaxInclusive + 1;
return value.compareTo(this.minInclusive) >= 0 && value.compareTo(maxExclusive) <= 0
? DataResult.success(value)
: DataResult.error(() -> "Value " + value + " outside of range [" + this.minInclusive + ":" + maxExclusive + "]", value);
}
);
}
@Override
public boolean createCycleButton() {
return true;
}
@Override
public CycleButton.ValueListSupplier<Integer> valueListSupplier() {
return CycleButton.ValueListSupplier.create(IntStream.range(this.minInclusive, this.maxInclusive() + 1).boxed().toList());
}
}
@OnlyIn(Dist.CLIENT)
interface CycleableValueSet<T> extends OptionInstance.ValueSet<T> {
CycleButton.ValueListSupplier<T> valueListSupplier();
default OptionInstance.CycleableValueSet.ValueSetter<T> valueSetter() {
return OptionInstance::set;
}
@Override
default Function<OptionInstance<T>, AbstractWidget> createButton(
OptionInstance.TooltipSupplier<T> tooltip, Options options, int x, int y, int width, Consumer<T> onValueChanged
) {
return instance -> CycleButton.<T>builder(instance.toString, instance::get)
.withValues(this.valueListSupplier())
.withTooltip(tooltip)
.create(x, y, width, 20, instance.caption, (button, value) -> {
this.valueSetter().set(instance, value);
options.save();
onValueChanged.accept(value);
});
}
@OnlyIn(Dist.CLIENT)
public interface ValueSetter<T> {
void set(final OptionInstance<T> instance, final T value);
}
}
@OnlyIn(Dist.CLIENT)
public record Enum<T>(List<T> values, Codec<T> codec) implements OptionInstance.CycleableValueSet<T> {
@Override
public Optional<T> validateValue(T value) {
return this.values.contains(value) ? Optional.of(value) : Optional.empty();
}
@Override
public CycleButton.ValueListSupplier<T> valueListSupplier() {
return CycleButton.ValueListSupplier.create(this.values);
}
}
@OnlyIn(Dist.CLIENT)
public record IntRange(int minInclusive, int maxInclusive, boolean applyValueImmediately) implements OptionInstance.IntRangeBase {
public IntRange(int minInclusive, int maxInclusive) {
this(minInclusive, maxInclusive, true);
}
public Optional<Integer> validateValue(Integer value) {
return value.compareTo(this.minInclusive()) >= 0 && value.compareTo(this.maxInclusive()) <= 0 ? Optional.of(value) : Optional.empty();
}
@Override
public Codec<Integer> codec() {
return Codec.intRange(this.minInclusive, this.maxInclusive + 1);
}
}
@OnlyIn(Dist.CLIENT)
interface IntRangeBase extends OptionInstance.SliderableValueSet<Integer> {
int minInclusive();
int maxInclusive();
default Optional<Integer> next(Integer current) {
return Optional.of(current + 1);
}
default Optional<Integer> previous(Integer current) {
return Optional.of(current - 1);
}
default double toSliderValue(Integer value) {
if (value == this.minInclusive()) {
return 0.0;
} else {
return value == this.maxInclusive() ? 1.0 : Mth.map(value.intValue() + 0.5, (double)this.minInclusive(), this.maxInclusive() + 1.0, 0.0, 1.0);
}
}
default Integer fromSliderValue(double slider) {
if (slider >= 1.0) {
slider = 0.99999F;
}
return Mth.floor(Mth.map(slider, 0.0, 1.0, (double)this.minInclusive(), this.maxInclusive() + 1.0));
}
default <R> OptionInstance.SliderableValueSet<R> xmap(IntFunction<? extends R> to, ToIntFunction<? super R> from, boolean discrete) {
return new OptionInstance.SliderableValueSet<R>() {
{
Objects.requireNonNull(IntRangeBase.this);
}
@Override
public Optional<R> validateValue(R value) {
return IntRangeBase.this.validateValue(from.applyAsInt(value)).map(to::apply);
}
@Override
public double toSliderValue(R value) {
return IntRangeBase.this.toSliderValue(from.applyAsInt(value));
}
@Override
public Optional<R> next(R current) {
if (!discrete) {
return Optional.empty();
} else {
int currentIndex = from.applyAsInt(current);
return (Optional<R>)Optional.of(to.apply(IntRangeBase.this.validateValue(currentIndex + 1).orElse(currentIndex)));
}
}
@Override
public Optional<R> previous(R current) {
if (!discrete) {
return Optional.empty();
} else {
int currentIndex = from.applyAsInt(current);
return (Optional<R>)Optional.of(to.apply(IntRangeBase.this.validateValue(currentIndex - 1).orElse(currentIndex)));
}
}
@Override
public R fromSliderValue(double slider) {
return (R)to.apply(IntRangeBase.this.fromSliderValue(slider));
}
@Override
public Codec<R> codec() {
return IntRangeBase.this.codec().xmap(to::apply, from::applyAsInt);
}
};
}
}
@OnlyIn(Dist.CLIENT)
public record LazyEnum<T>(Supplier<List<T>> values, Function<T, Optional<T>> validateValue, Codec<T> codec) implements OptionInstance.CycleableValueSet<T> {
@Override
public Optional<T> validateValue(T value) {
return this.validateValue.apply(value);
}
@Override
public CycleButton.ValueListSupplier<T> valueListSupplier() {
return CycleButton.ValueListSupplier.create(this.values.get());
}
}
@OnlyIn(Dist.CLIENT)
public static final class OptionInstanceSliderButton<N> extends AbstractOptionSliderButton implements ResettableOptionWidget {
private final OptionInstance<N> instance;
private final OptionInstance.SliderableValueSet<N> values;
private final OptionInstance.TooltipSupplier<N> tooltipSupplier;
private final Consumer<N> onValueChanged;
private @Nullable Long delayedApplyAt;
private final boolean applyValueImmediately;
private OptionInstanceSliderButton(
Options options,
int x,
int y,
int width,
int height,
OptionInstance<N> instance,
OptionInstance.SliderableValueSet<N> values,
OptionInstance.TooltipSupplier<N> tooltipSupplier,
Consumer<N> onValueChanged,
boolean applyValueImmediately
) {
super(options, x, y, width, height, values.toSliderValue(instance.get()));
this.instance = instance;
this.values = values;
this.tooltipSupplier = tooltipSupplier;
this.onValueChanged = onValueChanged;
this.applyValueImmediately = applyValueImmediately;
this.updateMessage();
}
@Override
protected void updateMessage() {
this.setMessage(this.instance.toString.apply(this.values.fromSliderValue(this.value)));
this.setTooltip(this.tooltipSupplier.apply(this.values.fromSliderValue(this.value)));
}
@Override
protected void applyValue() {
if (this.applyValueImmediately) {
this.applyUnsavedValue();
} else {
this.delayedApplyAt = Util.getMillis() + 600L;
}
}
public void applyUnsavedValue() {
N sliderValue = this.values.fromSliderValue(this.value);
if (!Objects.equals(sliderValue, this.instance.get())) {
this.instance.set(sliderValue);
this.onValueChanged.accept(this.instance.get());
}
}
@Override
public void resetValue() {
if (this.value != this.values.toSliderValue(this.instance.get())) {
this.value = this.values.toSliderValue(this.instance.get());
this.delayedApplyAt = null;
this.updateMessage();
}
}
@Override
public void extractWidgetRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) {
super.extractWidgetRenderState(graphics, mouseX, mouseY, a);
if (this.delayedApplyAt != null && Util.getMillis() >= this.delayedApplyAt) {
this.delayedApplyAt = null;
this.applyUnsavedValue();
this.resetValue();
}
}
@Override
public void onRelease(MouseButtonEvent event) {
super.onRelease(event);
if (this.applyValueImmediately) {
this.resetValue();
}
}
@Override
public boolean keyPressed(KeyEvent event) {
if (event.isSelection()) {
this.canChangeValue = !this.canChangeValue;
return true;
} else {
if (this.canChangeValue) {
boolean left = event.isLeft();
boolean right = event.isRight();
if (left) {
Optional<N> previous = this.values.previous(this.values.fromSliderValue(this.value));
if (previous.isPresent()) {
this.setValue(this.values.toSliderValue(previous.get()));
return true;
}
}
if (right) {
Optional<N> next = this.values.next(this.values.fromSliderValue(this.value));
if (next.isPresent()) {
this.setValue(this.values.toSliderValue(next.get()));
return true;
}
}
if (left || right) {
float direction = left ? -1.0F : 1.0F;
this.setValue(this.value + direction / (this.width - 8));
return true;
}
}
return false;
}
}
}
@OnlyIn(Dist.CLIENT)
public record SliderableEnum<T>(List<T> values, Codec<T> codec) implements OptionInstance.SliderableValueSet<T> {
@Override
public double toSliderValue(T value) {
if (value == this.values.getFirst()) {
return 0.0;
} else {
return value == this.values.getLast() ? 1.0 : Mth.map((double)this.values.indexOf(value), 0.0, (double)(this.values.size() - 1), 0.0, 1.0);
}
}
@Override
public Optional<T> next(T current) {
int currentIntex = this.values.indexOf(current);
int nextIndex = Mth.clamp(currentIntex + 1, 0, this.values.size() - 1);
return Optional.of(this.values.get(nextIndex));
}
@Override
public Optional<T> previous(T current) {
int currentIntex = this.values.indexOf(current);
int previousIndex = Mth.clamp(currentIntex - 1, 0, this.values.size() - 1);
return Optional.of(this.values.get(previousIndex));
}
@Override
public T fromSliderValue(double slider) {
if (slider >= 1.0) {
slider = 0.99999F;
}
int index = Mth.floor(Mth.map(slider, 0.0, 1.0, 0.0, (double)this.values.size()));
return this.values.get(Mth.clamp(index, 0, this.values.size() - 1));
}
@Override
public Optional<T> validateValue(T value) {
int index = this.values.indexOf(value);
return index > -1 ? Optional.of(value) : Optional.empty();
}
}
@OnlyIn(Dist.CLIENT)
interface SliderableOrCyclableValueSet<T> extends OptionInstance.SliderableValueSet<T>, OptionInstance.CycleableValueSet<T> {
boolean createCycleButton();
@Override
default Function<OptionInstance<T>, AbstractWidget> createButton(
OptionInstance.TooltipSupplier<T> tooltip, Options options, int x, int y, int width, Consumer<T> onValueChanged
) {
return this.createCycleButton()
? OptionInstance.CycleableValueSet.super.createButton(tooltip, options, x, y, width, onValueChanged)
: OptionInstance.SliderableValueSet.super.createButton(tooltip, options, x, y, width, onValueChanged);
}
}
@OnlyIn(Dist.CLIENT)
interface SliderableValueSet<T> extends OptionInstance.ValueSet<T> {
double toSliderValue(final T value);
default Optional<T> next(T current) {
return Optional.empty();
}
default Optional<T> previous(T current) {
return Optional.empty();
}
T fromSliderValue(final double slider);
default boolean applyValueImmediately() {
return true;
}
@Override
default Function<OptionInstance<T>, AbstractWidget> createButton(
OptionInstance.TooltipSupplier<T> tooltip, Options options, int x, int y, int width, Consumer<T> onValueChanged
) {
return instance -> new OptionInstance.OptionInstanceSliderButton<>(
options, x, y, width, 20, instance, this, tooltip, onValueChanged, this.applyValueImmediately()
);
}
}
@FunctionalInterface
@OnlyIn(Dist.CLIENT)
public interface TooltipSupplier<T> {
@Nullable Tooltip apply(T value);
}
@OnlyIn(Dist.CLIENT)
public static enum UnitDouble implements OptionInstance.SliderableValueSet<Double> {
INSTANCE;
public Optional<Double> validateValue(Double value) {
return value >= 0.0 && value <= 1.0 ? Optional.of(value) : Optional.empty();
}
public double toSliderValue(Double value) {
return value;
}
public Double fromSliderValue(double slider) {
return slider;
}
public <R> OptionInstance.SliderableValueSet<R> xmap(DoubleFunction<? extends R> to, ToDoubleFunction<? super R> from) {
return new OptionInstance.SliderableValueSet<R>() {
{
Objects.requireNonNull(UnitDouble.this);
}
@Override
public Optional<R> validateValue(R value) {
return UnitDouble.this.validateValue(from.applyAsDouble(value)).map(to::apply);
}
@Override
public double toSliderValue(R value) {
return UnitDouble.this.toSliderValue(from.applyAsDouble(value));
}
@Override
public R fromSliderValue(double slider) {
return (R)to.apply(UnitDouble.this.fromSliderValue(slider));
}
@Override
public Codec<R> codec() {
return UnitDouble.this.codec().xmap(to::apply, from::applyAsDouble);
}
};
}
@Override
public Codec<Double> codec() {
return Codec.withAlternative(Codec.doubleRange(0.0, 1.0), Codec.BOOL, b -> b ? 1.0 : 0.0);
}
}
@OnlyIn(Dist.CLIENT)
interface ValueSet<T> {
Function<OptionInstance<T>, AbstractWidget> createButton(
final OptionInstance.TooltipSupplier<T> tooltip, Options options, final int x, final int y, final int width, final Consumer<T> onValueChanged
);
Optional<T> validateValue(final T value);
Codec<T> codec();
}
}引用的其他类
-
- 引用位置:
方法调用 - 关联成员:
Minecraft.getInstance()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
CycleButton.ValueListSupplier.create()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Tooltip.create()
- 引用位置:
-
- 引用位置:
参数/字段/方法调用 - 关联成员:
Component.translatable()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Mth.clamp(), Mth.floor(), Mth.map()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Util.getMillis()
- 引用位置: