GuiRegistry.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. package me.lortseam.completeconfig.gui.cloth;
  2. import com.google.common.collect.Lists;
  3. import com.google.common.collect.MoreCollectors;
  4. import com.google.common.reflect.TypeToken;
  5. import me.lortseam.completeconfig.data.Entry;
  6. import me.lortseam.completeconfig.data.EnumOptions;
  7. import me.lortseam.completeconfig.util.TypeUtils;
  8. import me.shedaniel.clothconfig2.api.AbstractConfigListEntry;
  9. import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
  10. import me.shedaniel.clothconfig2.impl.builders.DropdownMenuBuilder;
  11. import me.shedaniel.clothconfig2.impl.builders.FieldBuilder;
  12. import net.fabricmc.api.EnvType;
  13. import net.fabricmc.api.Environment;
  14. import org.apache.commons.lang3.ArrayUtils;
  15. import java.lang.reflect.Type;
  16. import java.util.ArrayList;
  17. import java.util.Arrays;
  18. import java.util.List;
  19. import java.util.Optional;
  20. import java.util.function.Function;
  21. @Environment(EnvType.CLIENT)
  22. public class GuiRegistry {
  23. public static <T, A extends AbstractConfigListEntry> A build(Function<ConfigEntryBuilder, FieldBuilder<T, A>> builder, boolean requiresRestart) {
  24. FieldBuilder<T, A> fieldBuilder = builder.apply(ConfigEntryBuilder.create());
  25. fieldBuilder.requireRestart(requiresRestart);
  26. return fieldBuilder.build();
  27. }
  28. private final List<GuiProviderRegistration> registrations = new ArrayList<>();
  29. GuiRegistry() {
  30. registerDefaultProviders();
  31. }
  32. public <T> void registerProvider(GuiProvider<T> provider, GuiProviderPredicate<T> predicate, Type... types) {
  33. registrations.add(new GuiProviderRegistration<>(predicate.and((field, extras) -> {
  34. if (types.length == 0) {
  35. return true;
  36. }
  37. return ArrayUtils.contains(types, TypeUtils.getFieldType(field));
  38. }), provider));
  39. }
  40. public void registerProvider(GuiProvider<?> provider, Type... types) {
  41. if (types.length == 0) {
  42. throw new IllegalArgumentException("Types must not be empty");
  43. }
  44. registerProvider(provider, (field, extras) -> true, types);
  45. }
  46. private void registerBoundedProvider(GuiProvider<?> provider, boolean slider, Type... types) {
  47. registerProvider(provider, (field, extras) -> extras.getBounds() != null && extras.getBounds().isSlider() == slider, types);
  48. }
  49. private void registerEnumProvider(GuiProvider<? extends Enum> provider, EnumOptions.DisplayType enumDisplayType) {
  50. registerProvider(provider, (field, extras) -> Enum.class.isAssignableFrom(field.getType()) && extras.getEnumOptions().getDisplayType() == enumDisplayType);
  51. }
  52. private void registerDefaultProviders() {
  53. registerProvider((GuiProvider<Boolean>) entry -> build(
  54. builder -> builder
  55. .startBooleanToggle(entry.getText(), entry.getValue())
  56. .setDefaultValue(entry.getDefaultValue())
  57. .setTooltip(entry.getTooltip())
  58. .setSaveConsumer(entry::setValue),
  59. entry.requiresRestart()
  60. ), boolean.class, Boolean.class);
  61. registerProvider((GuiProvider<Integer>) entry -> build(
  62. builder -> builder
  63. .startIntField(entry.getText(), entry.getValue())
  64. .setDefaultValue(entry.getDefaultValue())
  65. .setTooltip(entry.getTooltip())
  66. .setSaveConsumer(entry::setValue),
  67. entry.requiresRestart()
  68. ), int.class, Integer.class);
  69. registerBoundedProvider((GuiProvider<Integer>) entry -> build(
  70. builder -> builder
  71. .startIntField(entry.getText(), entry.getValue())
  72. .setDefaultValue(entry.getDefaultValue())
  73. .setMin(entry.getExtras().getBounds().getMin())
  74. .setMax(entry.getExtras().getBounds().getMax())
  75. .setTooltip(entry.getTooltip())
  76. .setSaveConsumer(entry::setValue),
  77. entry.requiresRestart()
  78. ), false, int.class, Integer.class);
  79. registerBoundedProvider((GuiProvider<Integer>) entry -> build(
  80. builder -> builder
  81. .startIntSlider(entry.getText(), entry.getValue(), entry.getExtras().getBounds().getMin(), entry.getExtras().getBounds().getMax())
  82. .setDefaultValue(entry.getDefaultValue())
  83. .setTooltip(entry.getTooltip())
  84. .setSaveConsumer(entry::setValue),
  85. entry.requiresRestart()
  86. ), true, int.class, Integer.class);
  87. registerProvider((GuiProvider<Long>) entry -> build(
  88. builder -> builder
  89. .startLongField(entry.getText(), entry.getValue())
  90. .setDefaultValue(entry.getDefaultValue())
  91. .setTooltip(entry.getTooltip())
  92. .setSaveConsumer(entry::setValue),
  93. entry.requiresRestart()
  94. ), long.class, Long.class);
  95. registerBoundedProvider((GuiProvider<Long>) entry -> build(
  96. builder -> builder
  97. .startLongField(entry.getText(), entry.getValue())
  98. .setDefaultValue(entry.getDefaultValue())
  99. .setMin(entry.getExtras().getBounds().getMin())
  100. .setMax(entry.getExtras().getBounds().getMax())
  101. .setTooltip(entry.getTooltip())
  102. .setSaveConsumer(entry::setValue),
  103. entry.requiresRestart()
  104. ), false, long.class, Long.class);
  105. registerBoundedProvider((GuiProvider<Long>) entry -> build(
  106. builder -> builder
  107. .startLongSlider(entry.getText(), entry.getValue(), entry.getExtras().getBounds().getMin(), entry.getExtras().getBounds().getMax())
  108. .setDefaultValue(entry.getDefaultValue())
  109. .setTooltip(entry.getTooltip())
  110. .setSaveConsumer(entry::setValue),
  111. entry.requiresRestart()
  112. ), true, long.class, Long.class);
  113. registerProvider((GuiProvider<Float>) entry -> build(
  114. builder -> builder
  115. .startFloatField(entry.getText(), entry.getValue())
  116. .setDefaultValue(entry.getDefaultValue())
  117. .setTooltip(entry.getTooltip())
  118. .setSaveConsumer(entry::setValue),
  119. entry.requiresRestart()
  120. ), float.class, Float.class);
  121. registerBoundedProvider((GuiProvider<Float>) entry -> build(
  122. builder -> builder
  123. .startFloatField(entry.getText(), entry.getValue())
  124. .setDefaultValue(entry.getDefaultValue())
  125. .setMin(entry.getExtras().getBounds().getMin())
  126. .setMax(entry.getExtras().getBounds().getMax())
  127. .setTooltip(entry.getTooltip())
  128. .setSaveConsumer(entry::setValue),
  129. entry.requiresRestart()
  130. ), false, float.class, Float.class);
  131. registerProvider((GuiProvider<Double>) entry -> build(
  132. builder -> builder
  133. .startDoubleField(entry.getText(), entry.getValue())
  134. .setDefaultValue(entry.getDefaultValue())
  135. .setTooltip(entry.getTooltip())
  136. .setSaveConsumer(entry::setValue),
  137. entry.requiresRestart()
  138. ), double.class, Double.class);
  139. registerBoundedProvider((GuiProvider<Double>) entry -> build(
  140. builder -> builder
  141. .startDoubleField(entry.getText(), entry.getValue())
  142. .setDefaultValue(entry.getDefaultValue())
  143. .setMin(entry.getExtras().getBounds().getMin())
  144. .setMax(entry.getExtras().getBounds().getMax())
  145. .setTooltip(entry.getTooltip())
  146. .setSaveConsumer(entry::setValue),
  147. entry.requiresRestart()
  148. ), false, double.class, Double.class);
  149. registerProvider((GuiProvider<String>) entry -> build(
  150. builder -> builder
  151. .startStrField(entry.getText(), entry.getValue())
  152. .setDefaultValue(entry.getDefaultValue())
  153. .setTooltip(entry.getTooltip())
  154. .setSaveConsumer(entry::setValue),
  155. entry.requiresRestart()
  156. ), String.class);
  157. registerEnumProvider((GuiProvider<? extends Enum<?>>) entry -> build(
  158. builder -> builder
  159. .startEnumSelector(entry.getText(), entry.getTypeClass(), entry.getValue())
  160. .setDefaultValue(entry.getDefaultValue())
  161. .setTooltip(entry.getTooltip())
  162. .setEnumNameProvider(entry.getExtras().getEnumOptions().getNameProvider())
  163. .setSaveConsumer(entry::setValue),
  164. entry.requiresRestart()
  165. ), EnumOptions.DisplayType.BUTTON);
  166. registerEnumProvider((GuiProvider<? extends Enum>) entry -> {
  167. List<Enum> enumValues = Arrays.asList(((Class<? extends Enum>) entry.getTypeClass()).getEnumConstants());
  168. return build(
  169. builder -> builder
  170. .startDropdownMenu(entry.getText(), DropdownMenuBuilder.TopCellElementBuilder.of(
  171. entry.getValue(),
  172. enumTranslation -> enumValues.stream().filter(enumValue -> entry.getExtras().getEnumOptions().getNameProvider().apply(enumValue).getString().equals(enumTranslation)).collect(MoreCollectors.toOptional()).orElse(null),
  173. entry.getExtras().getEnumOptions().getNameProvider()
  174. ), DropdownMenuBuilder.CellCreatorBuilder.of(entry.getExtras().getEnumOptions().getNameProvider()))
  175. .setSelections(enumValues)
  176. .setDefaultValue(entry.getDefaultValue())
  177. .setSaveConsumer(entry::setValue),
  178. entry.requiresRestart()
  179. );
  180. }, EnumOptions.DisplayType.DROPDOWN);
  181. registerProvider((GuiProvider<List<Integer>>) entry -> build(
  182. builder -> builder
  183. .startIntList(entry.getText(), entry.getValue())
  184. .setDefaultValue(entry.getDefaultValue())
  185. .setTooltip(entry.getTooltip())
  186. .setSaveConsumer(entry::setValue),
  187. entry.requiresRestart()
  188. ), new TypeToken<List<Integer>>() {}.getType());
  189. registerProvider((GuiProvider<List<Long>>) entry -> build(
  190. builder -> builder
  191. .startLongList(entry.getText(), entry.getValue())
  192. .setDefaultValue(entry.getDefaultValue())
  193. .setTooltip(entry.getTooltip())
  194. .setSaveConsumer(entry::setValue),
  195. entry.requiresRestart()
  196. ), new TypeToken<List<Long>>() {}.getType());
  197. registerProvider((GuiProvider<List<Float>>) entry -> build(
  198. builder -> builder
  199. .startFloatList(entry.getText(), entry.getValue())
  200. .setDefaultValue(entry.getDefaultValue())
  201. .setTooltip(entry.getTooltip())
  202. .setSaveConsumer(entry::setValue),
  203. entry.requiresRestart()
  204. ), new TypeToken<List<Float>>() {}.getType());
  205. registerProvider((GuiProvider<List<Double>>) entry -> build(
  206. builder -> builder
  207. .startDoubleList(entry.getText(), entry.getValue())
  208. .setDefaultValue(entry.getDefaultValue())
  209. .setTooltip(entry.getTooltip())
  210. .setSaveConsumer(entry::setValue),
  211. entry.requiresRestart()
  212. ), new TypeToken<List<Double>>() {}.getType());
  213. registerProvider((GuiProvider<List<String>>) entry -> build(
  214. builder -> builder
  215. .startStrList(entry.getText(), entry.getValue())
  216. .setDefaultValue(entry.getDefaultValue())
  217. .setTooltip(entry.getTooltip())
  218. .setSaveConsumer(entry::setValue),
  219. entry.requiresRestart()
  220. ), new TypeToken<List<String>>() {}.getType());
  221. }
  222. <T> Optional<GuiProvider<T>> getProvider(Entry<T> entry) {
  223. for (GuiProviderRegistration<?> registration : Lists.reverse(registrations)) {
  224. if (registration.test(entry)) {
  225. return Optional.of((GuiProvider<T>) registration.getProvider());
  226. }
  227. }
  228. return Optional.empty();
  229. }
  230. }