IntegerSliderEntry.java 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * This file is part of Cloth Config.
  3. * Copyright (C) 2020 - 2021 shedaniel
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 3 of the License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public License
  16. * along with this program; if not, write to the Free Software Foundation,
  17. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. */
  19. package me.shedaniel.clothconfig2.gui.entries;
  20. import com.google.common.collect.Lists;
  21. import com.mojang.blaze3d.platform.Window;
  22. import com.mojang.blaze3d.vertex.PoseStack;
  23. import net.fabricmc.api.EnvType;
  24. import net.fabricmc.api.Environment;
  25. import net.minecraft.client.Minecraft;
  26. import net.minecraft.client.gui.chat.NarratorChatListener;
  27. import net.minecraft.client.gui.components.AbstractSliderButton;
  28. import net.minecraft.client.gui.components.Button;
  29. import net.minecraft.client.gui.components.events.GuiEventListener;
  30. import net.minecraft.network.chat.Component;
  31. import net.minecraft.network.chat.TextComponent;
  32. import net.minecraft.util.Mth;
  33. import org.jetbrains.annotations.ApiStatus;
  34. import java.util.List;
  35. import java.util.Optional;
  36. import java.util.concurrent.atomic.AtomicInteger;
  37. import java.util.function.Consumer;
  38. import java.util.function.Function;
  39. import java.util.function.Supplier;
  40. @Environment(EnvType.CLIENT)
  41. public class IntegerSliderEntry extends TooltipListEntry<Integer> {
  42. protected Slider sliderWidget;
  43. protected Button resetButton;
  44. protected AtomicInteger value;
  45. protected final long orginial;
  46. private int minimum, maximum;
  47. private final Consumer<Integer> saveConsumer;
  48. private final Supplier<Integer> defaultValue;
  49. private Function<Integer, Component> textGetter = integer -> new TextComponent(String.format("Value: %d", integer));
  50. private final List<GuiEventListener> widgets;
  51. @ApiStatus.Internal
  52. @Deprecated
  53. public IntegerSliderEntry(Component fieldName, int minimum, int maximum, int value, Component resetButtonKey, Supplier<Integer> defaultValue, Consumer<Integer> saveConsumer) {
  54. this(fieldName, minimum, maximum, value, resetButtonKey, defaultValue, saveConsumer, null);
  55. }
  56. @ApiStatus.Internal
  57. @Deprecated
  58. public IntegerSliderEntry(Component fieldName, int minimum, int maximum, int value, Component resetButtonKey, Supplier<Integer> defaultValue, Consumer<Integer> saveConsumer, Supplier<Optional<Component[]>> tooltipSupplier) {
  59. this(fieldName, minimum, maximum, value, resetButtonKey, defaultValue, saveConsumer, tooltipSupplier, false);
  60. }
  61. @ApiStatus.Internal
  62. @Deprecated
  63. public IntegerSliderEntry(Component fieldName, int minimum, int maximum, int value, Component resetButtonKey, Supplier<Integer> defaultValue, Consumer<Integer> saveConsumer, Supplier<Optional<Component[]>> tooltipSupplier, boolean requiresRestart) {
  64. super(fieldName, tooltipSupplier, requiresRestart);
  65. this.orginial = value;
  66. this.defaultValue = defaultValue;
  67. this.value = new AtomicInteger(value);
  68. this.saveConsumer = saveConsumer;
  69. this.maximum = maximum;
  70. this.minimum = minimum;
  71. this.sliderWidget = new Slider(0, 0, 152, 20, ((double) this.value.get() - minimum) / Math.abs(maximum - minimum));
  72. this.resetButton = new Button(0, 0, Minecraft.getInstance().font.width(resetButtonKey) + 6, 20, resetButtonKey, widget -> {
  73. setValue(defaultValue.get());
  74. });
  75. this.sliderWidget.setMessage(textGetter.apply(IntegerSliderEntry.this.value.get()));
  76. this.widgets = Lists.newArrayList(sliderWidget, resetButton);
  77. }
  78. @Override
  79. public void save() {
  80. if (saveConsumer != null)
  81. saveConsumer.accept(getValue());
  82. }
  83. public Function<Integer, Component> getTextGetter() {
  84. return textGetter;
  85. }
  86. public IntegerSliderEntry setTextGetter(Function<Integer, Component> textGetter) {
  87. this.textGetter = textGetter;
  88. this.sliderWidget.setMessage(textGetter.apply(IntegerSliderEntry.this.value.get()));
  89. return this;
  90. }
  91. @Override
  92. public Integer getValue() {
  93. return value.get();
  94. }
  95. @Deprecated
  96. public void setValue(int value) {
  97. sliderWidget.setValue((Mth.clamp(value, minimum, maximum) - minimum) / (double) Math.abs(maximum - minimum));
  98. this.value.set(Math.min(Math.max(value, minimum), maximum));
  99. sliderWidget.updateMessage();
  100. }
  101. @Override
  102. public boolean isEdited() {
  103. return super.isEdited() || getValue() != orginial;
  104. }
  105. @Override
  106. public Optional<Integer> getDefaultValue() {
  107. return defaultValue == null ? Optional.empty() : Optional.ofNullable(defaultValue.get());
  108. }
  109. @Override
  110. public List<? extends GuiEventListener> children() {
  111. return widgets;
  112. }
  113. public IntegerSliderEntry setMaximum(int maximum) {
  114. this.maximum = maximum;
  115. return this;
  116. }
  117. public IntegerSliderEntry setMinimum(int minimum) {
  118. this.minimum = minimum;
  119. return this;
  120. }
  121. @Override
  122. public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isHovered, float delta) {
  123. super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isHovered, delta);
  124. Window window = Minecraft.getInstance().getWindow();
  125. this.resetButton.active = isEditable() && getDefaultValue().isPresent() && defaultValue.get() != value.get();
  126. this.resetButton.y = y;
  127. this.sliderWidget.active = isEditable();
  128. this.sliderWidget.y = y;
  129. Component displayedFieldName = getDisplayedFieldName();
  130. if (Minecraft.getInstance().font.isBidirectional()) {
  131. Minecraft.getInstance().font.drawShadow(matrices, displayedFieldName.getVisualOrderText(), window.getGuiScaledWidth() - x - Minecraft.getInstance().font.width(displayedFieldName), y + 6, getPreferredTextColor());
  132. this.resetButton.x = x;
  133. this.sliderWidget.x = x + resetButton.getWidth() + 1;
  134. } else {
  135. Minecraft.getInstance().font.drawShadow(matrices, displayedFieldName.getVisualOrderText(), x, y + 6, getPreferredTextColor());
  136. this.resetButton.x = x + entryWidth - resetButton.getWidth();
  137. this.sliderWidget.x = x + entryWidth - 150;
  138. }
  139. this.sliderWidget.setWidth(150 - resetButton.getWidth() - 2);
  140. resetButton.render(matrices, mouseX, mouseY, delta);
  141. sliderWidget.render(matrices, mouseX, mouseY, delta);
  142. }
  143. private class Slider extends AbstractSliderButton {
  144. protected Slider(int int_1, int int_2, int int_3, int int_4, double double_1) {
  145. super(int_1, int_2, int_3, int_4, NarratorChatListener.NO_TITLE, double_1);
  146. }
  147. @Override
  148. public void updateMessage() {
  149. setMessage(textGetter.apply(IntegerSliderEntry.this.value.get()));
  150. }
  151. @Override
  152. protected void applyValue() {
  153. IntegerSliderEntry.this.value.set((int) (minimum + Math.abs(maximum - minimum) * value));
  154. }
  155. @Override
  156. public boolean keyPressed(int int_1, int int_2, int int_3) {
  157. if (!isEditable())
  158. return false;
  159. return super.keyPressed(int_1, int_2, int_3);
  160. }
  161. @Override
  162. public boolean mouseDragged(double double_1, double double_2, int int_1, double double_3, double double_4) {
  163. if (!isEditable())
  164. return false;
  165. return super.mouseDragged(double_1, double_2, int_1, double_3, double_4);
  166. }
  167. public double getProgress() {
  168. return value;
  169. }
  170. public void setProgress(double integer) {
  171. this.value = integer;
  172. }
  173. public void setValue(double integer) {
  174. this.value = integer;
  175. }
  176. }
  177. }