package me.shedaniel.clothconfig2.gui.entries; import com.google.common.collect.Lists; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.Element; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.SliderWidget; import net.minecraft.client.util.NarratorManager; import net.minecraft.client.util.Window; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.LiteralText; import net.minecraft.text.Text; import net.minecraft.util.math.MathHelper; import org.jetbrains.annotations.ApiStatus; import java.util.List; import java.util.Optional; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; @Environment(EnvType.CLIENT) public class LongSliderEntry extends TooltipListEntry { protected Slider sliderWidget; protected ButtonWidget resetButton; protected AtomicLong value; private long minimum, maximum; private Consumer saveConsumer; private Supplier defaultValue; private Function textGetter = value -> new LiteralText(String.format("Value: %d", value)); private List widgets; @ApiStatus.Internal @Deprecated public LongSliderEntry(Text fieldName, long minimum, long maximum, long value, Consumer saveConsumer, Text resetButtonKey, Supplier defaultValue) { this(fieldName, minimum, maximum, value, saveConsumer, resetButtonKey, defaultValue, null); } @ApiStatus.Internal @Deprecated public LongSliderEntry(Text fieldName, long minimum, long maximum, long value, Consumer saveConsumer, Text resetButtonKey, Supplier defaultValue, Supplier> tooltipSupplier) { this(fieldName, minimum, maximum, value, saveConsumer, resetButtonKey, defaultValue, tooltipSupplier, false); } @ApiStatus.Internal @Deprecated public LongSliderEntry(Text fieldName, long minimum, long maximum, long value, Consumer saveConsumer, Text resetButtonKey, Supplier defaultValue, Supplier> tooltipSupplier, boolean requiresRestart) { super(fieldName, tooltipSupplier, requiresRestart); this.defaultValue = defaultValue; this.value = new AtomicLong(value); this.saveConsumer = saveConsumer; this.maximum = maximum; this.minimum = minimum; this.sliderWidget = new Slider(0, 0, 152, 20, ((double) LongSliderEntry.this.value.get() - minimum) / Math.abs(maximum - minimum)); this.resetButton = new ButtonWidget(0, 0, MinecraftClient.getInstance().textRenderer.method_27525(resetButtonKey) + 6, 20, resetButtonKey, widget -> { setValue(defaultValue.get()); getScreen().setEdited(true, isRequiresRestart()); }); this.sliderWidget.setMessage(textGetter.apply(LongSliderEntry.this.value.get())); this.widgets = Lists.newArrayList(sliderWidget, resetButton); } @Override public void save() { if (saveConsumer != null) saveConsumer.accept(getValue()); } public Function getTextGetter() { return textGetter; } public LongSliderEntry setTextGetter(Function textGetter) { this.textGetter = textGetter; this.sliderWidget.setMessage(textGetter.apply(LongSliderEntry.this.value.get())); return this; } @Override public Long getValue() { return value.get(); } @Deprecated public void setValue(long value) { sliderWidget.setValue((MathHelper.clamp(value, minimum, maximum) - minimum) / (double) Math.abs(maximum - minimum)); this.value.set(Math.min(Math.max(value, minimum), maximum)); sliderWidget.updateMessage(); } @Override public Optional getDefaultValue() { return defaultValue == null ? Optional.empty() : Optional.ofNullable(defaultValue.get()); } @Override public List children() { return widgets; } public LongSliderEntry setMaximum(long maximum) { this.maximum = maximum; return this; } public LongSliderEntry setMinimum(long minimum) { this.minimum = minimum; return this; } @Override public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) { super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta); Window window = MinecraftClient.getInstance().getWindow(); this.resetButton.active = isEditable() && getDefaultValue().isPresent() && defaultValue.get() != value.get(); this.resetButton.y = y; this.sliderWidget.active = isEditable(); this.sliderWidget.y = y; if (MinecraftClient.getInstance().textRenderer.isRightToLeft()) { MinecraftClient.getInstance().textRenderer.method_27517(matrices, getFieldName(), window.getScaledWidth() - x - MinecraftClient.getInstance().textRenderer.method_27525(getFieldName()), y + 5, getPreferredTextColor()); this.resetButton.x = x; this.sliderWidget.x = x + resetButton.getWidth() + 1; } else { MinecraftClient.getInstance().textRenderer.method_27517(matrices, getFieldName(), x, y + 5, getPreferredTextColor()); this.resetButton.x = x + entryWidth - resetButton.getWidth(); this.sliderWidget.x = x + entryWidth - 150; } this.sliderWidget.setWidth(150 - resetButton.getWidth() - 2); resetButton.render(matrices, mouseX, mouseY, delta); sliderWidget.render(matrices, mouseX, mouseY, delta); } private class Slider extends SliderWidget { protected Slider(int int_1, int int_2, int int_3, int int_4, double double_1) { super(int_1, int_2, int_3, int_4, NarratorManager.EMPTY, double_1); } @Override public void updateMessage() { setMessage(textGetter.apply(LongSliderEntry.this.value.get())); } @Override protected void applyValue() { LongSliderEntry.this.value.set((long) (minimum + Math.abs(maximum - minimum) * value)); getScreen().setEdited(true, isRequiresRestart()); } @Override public boolean keyPressed(int int_1, int int_2, int int_3) { if (!isEditable()) return false; return super.keyPressed(int_1, int_2, int_3); } @Override public boolean mouseDragged(double double_1, double double_2, int int_1, double double_3, double double_4) { if (!isEditable()) return false; return super.mouseDragged(double_1, double_2, int_1, double_3, double_4); } public double getValue() { return value; } public void setValue(double integer) { this.value = integer; } } }