Lortseam 4 жил өмнө
parent
commit
12fe907c34

+ 4 - 0
src/main/java/me/lortseam/completeconfig/api/ConfigGroup.java

@@ -16,4 +16,8 @@ public interface ConfigGroup extends ConfigContainer {
         return CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, getClass().getSimpleName());
     }
 
+    default String[] getTooltipTranslationKeys() {
+        return null;
+    }
+
 }

+ 12 - 91
src/main/java/me/lortseam/completeconfig/data/Collection.java

@@ -1,106 +1,27 @@
 package me.lortseam.completeconfig.data;
 
 import lombok.extern.log4j.Log4j2;
-import me.lortseam.completeconfig.api.ConfigContainer;
-import me.lortseam.completeconfig.api.ConfigGroup;
-import me.lortseam.completeconfig.data.structure.FlatDataPart;
 import me.lortseam.completeconfig.data.text.TranslationIdentifier;
-import me.lortseam.completeconfig.exception.IllegalAnnotationTargetException;
 import net.minecraft.text.Text;
+import org.apache.commons.lang3.ArrayUtils;
 
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Modifier;
-import java.util.*;
-import java.util.stream.Collectors;
+import java.util.Arrays;
+import java.util.Optional;
 
 @Log4j2
-public class Collection implements FlatDataPart<ConfigMap> {
+public class Collection extends Node {
 
-    protected final TranslationIdentifier translation;
-    private final EntryMap entries;
-    private final CollectionMap collections;
+    private final TranslationIdentifier[] customTooltipTranslation;
 
-    Collection(TranslationIdentifier translation) {
-        this.translation = translation;
-        entries = new EntryMap(translation);
-        collections = new CollectionMap(translation);
+    Collection(TranslationIdentifier translation, String[] customTooltipTranslationKeys) {
+        super(translation);
+        customTooltipTranslation = ArrayUtils.isNotEmpty(customTooltipTranslationKeys) ? Arrays.stream(customTooltipTranslationKeys).map(key -> translation.root().appendKey(key)).toArray(TranslationIdentifier[]::new) : null;
     }
 
-    public Text getText() {
-        return translation.toText();
-    }
-
-    public java.util.Collection<Entry> getEntries() {
-        return Collections.unmodifiableCollection(entries.values());
-    }
-
-    public java.util.Collection<Collection> getCollections() {
-        return Collections.unmodifiableCollection(collections.values());
-    }
-
-    void resolve(ConfigContainer container) {
-        entries.resolve(container);
-        List<ConfigContainer> containers = new ArrayList<>();
-        for (Class<? extends ConfigContainer> clazz : container.getConfigClasses()) {
-            containers.addAll(Arrays.stream(clazz.getDeclaredFields()).filter(field -> {
-                if (container.isConfigPOJO()) {
-                    return ConfigContainer.class.isAssignableFrom(field.getType());
-                }
-                if (field.isAnnotationPresent(ConfigContainer.Transitive.class)) {
-                    if (!ConfigContainer.class.isAssignableFrom(field.getType())) {
-                        throw new IllegalAnnotationTargetException("Transitive entry " + field + " must implement " + ConfigContainer.class.getSimpleName());
-                    }
-                    return true;
-                }
-                return false;
-            }).map(field -> {
-                if (!field.isAccessible()) {
-                    field.setAccessible(true);
-                }
-                try {
-                    return (ConfigContainer) field.get(container);
-                } catch (IllegalAccessException e) {
-                    throw new RuntimeException(e);
-                }
-            }).collect(Collectors.toList()));
-            if (container.isConfigPOJO()) {
-                resolve(Arrays.stream(clazz.getDeclaredClasses()).filter(nestedClass -> {
-                    return ConfigContainer.class.isAssignableFrom(nestedClass) && Modifier.isStatic(nestedClass.getModifiers());
-                }).map(nestedClass -> {
-                    try {
-                        Constructor<? extends ConfigContainer> constructor = (Constructor<? extends ConfigContainer>) nestedClass.getDeclaredConstructor();
-                        if (!constructor.isAccessible()) {
-                            constructor.setAccessible(true);
-                        }
-                        return constructor.newInstance();
-                    } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
-                        throw new RuntimeException("Failed to instantiate nested class " + nestedClass, e);
-                    }
-                }).filter(Objects::nonNull).collect(Collectors.toList()));
-            }
-        }
-        containers.addAll(Arrays.asList(container.getTransitiveContainers()));
-        resolve(containers);
-    }
-
-    protected void resolve(java.util.Collection<ConfigContainer> containers) {
-        for (ConfigContainer c : containers) {
-            if (c instanceof ConfigGroup) {
-                collections.resolve((ConfigGroup) c);
-            } else {
-                resolve(c);
-            }
-        }
-    }
-
-    @Override
-    public Iterable<ConfigMap> getChildren() {
-        return Arrays.asList(entries, collections);
-    }
-
-    boolean isEmpty() {
-        return entries.isEmpty() && collections.isEmpty();
+    public Optional<Text[]> getTooltipTranslation() {
+        return (customTooltipTranslation != null ? Optional.of(customTooltipTranslation) : translation.appendTooltip()).map(lines -> {
+            return Arrays.stream(lines).map(TranslationIdentifier::toText).toArray(Text[]::new);
+        });
     }
 
 }

+ 1 - 1
src/main/java/me/lortseam/completeconfig/data/CollectionMap.java

@@ -13,7 +13,7 @@ public class CollectionMap extends ConfigMap<Collection> {
 
     void resolve(ConfigGroup group) {
         String groupID = group.getGroupID();
-        Collection collection = new Collection(translation.append(groupID));
+        Collection collection = new Collection(translation.append(groupID), group.getTooltipTranslationKeys());
         collection.resolve(group);
         if (collection.isEmpty()) {
             logger.warn("[CompleteConfig] Group " + groupID + " is empty!");

+ 1 - 1
src/main/java/me/lortseam/completeconfig/data/Config.java

@@ -10,7 +10,7 @@ import net.fabricmc.loader.api.FabricLoader;
 import java.util.*;
 
 @Log4j2
-public class Config extends Collection {
+public class Config extends Node {
 
     private static final Set<Config> configs = new HashSet<>();
 

+ 3 - 12
src/main/java/me/lortseam/completeconfig/data/Entry.java

@@ -163,18 +163,9 @@ public class Entry<T> extends EntryBase<T> implements DataPart {
     }
 
     public Optional<Text[]> getTooltip() {
-        TranslationIdentifier[] translation;
-        if (customTooltipTranslation != null) {
-            translation = customTooltipTranslation;
-        } else {
-            Optional<TranslationIdentifier[]> defaultTooltip = getTranslation().appendTooltip();
-            if (defaultTooltip.isPresent()) {
-                translation = defaultTooltip.get();
-            } else {
-                return Optional.empty();
-            }
-        }
-        return Optional.of(Arrays.stream(translation).map(TranslationIdentifier::toText).toArray(Text[]::new));
+        return (customTooltipTranslation != null ? Optional.of(customTooltipTranslation) : getTranslation().appendTooltip()).map(lines -> {
+            return Arrays.stream(lines).map(TranslationIdentifier::toText).toArray(Text[]::new);
+        });
     }
 
     public boolean requiresRestart() {

+ 104 - 0
src/main/java/me/lortseam/completeconfig/data/Node.java

@@ -0,0 +1,104 @@
+package me.lortseam.completeconfig.data;
+
+import me.lortseam.completeconfig.api.ConfigContainer;
+import me.lortseam.completeconfig.api.ConfigGroup;
+import me.lortseam.completeconfig.data.structure.FlatDataPart;
+import me.lortseam.completeconfig.data.text.TranslationIdentifier;
+import me.lortseam.completeconfig.exception.IllegalAnnotationTargetException;
+import net.minecraft.text.Text;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+import java.util.*;
+import java.util.stream.Collectors;
+
+abstract class Node implements FlatDataPart<ConfigMap> {
+
+    protected final TranslationIdentifier translation;
+    private final EntryMap entries;
+    private final CollectionMap collections;
+
+    Node(TranslationIdentifier translation) {
+        this.translation = translation;
+        entries = new EntryMap(translation);
+        collections = new CollectionMap(translation);
+    }
+
+    public Text getText() {
+        return translation.toText();
+    }
+
+    public java.util.Collection<Entry> getEntries() {
+        return Collections.unmodifiableCollection(entries.values());
+    }
+
+    public java.util.Collection<Collection> getCollections() {
+        return Collections.unmodifiableCollection(collections.values());
+    }
+
+    void resolve(ConfigContainer container) {
+        entries.resolve(container);
+        List<ConfigContainer> containers = new ArrayList<>();
+        for (Class<? extends ConfigContainer> clazz : container.getConfigClasses()) {
+            containers.addAll(Arrays.stream(clazz.getDeclaredFields()).filter(field -> {
+                if (container.isConfigPOJO()) {
+                    return ConfigContainer.class.isAssignableFrom(field.getType());
+                }
+                if (field.isAnnotationPresent(ConfigContainer.Transitive.class)) {
+                    if (!ConfigContainer.class.isAssignableFrom(field.getType())) {
+                        throw new IllegalAnnotationTargetException("Transitive entry " + field + " must implement " + ConfigContainer.class.getSimpleName());
+                    }
+                    return true;
+                }
+                return false;
+            }).map(field -> {
+                if (!field.isAccessible()) {
+                    field.setAccessible(true);
+                }
+                try {
+                    return (ConfigContainer) field.get(container);
+                } catch (IllegalAccessException e) {
+                    throw new RuntimeException(e);
+                }
+            }).collect(Collectors.toList()));
+            if (container.isConfigPOJO()) {
+                resolve(Arrays.stream(clazz.getDeclaredClasses()).filter(nestedClass -> {
+                    return ConfigContainer.class.isAssignableFrom(nestedClass) && Modifier.isStatic(nestedClass.getModifiers());
+                }).map(nestedClass -> {
+                    try {
+                        Constructor<? extends ConfigContainer> constructor = (Constructor<? extends ConfigContainer>) nestedClass.getDeclaredConstructor();
+                        if (!constructor.isAccessible()) {
+                            constructor.setAccessible(true);
+                        }
+                        return constructor.newInstance();
+                    } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
+                        throw new RuntimeException("Failed to instantiate nested class " + nestedClass, e);
+                    }
+                }).filter(Objects::nonNull).collect(Collectors.toList()));
+            }
+        }
+        containers.addAll(Arrays.asList(container.getTransitiveContainers()));
+        resolve(containers);
+    }
+
+    protected void resolve(java.util.Collection<ConfigContainer> containers) {
+        for (ConfigContainer c : containers) {
+            if (c instanceof ConfigGroup) {
+                collections.resolve((ConfigGroup) c);
+            } else {
+                resolve(c);
+            }
+        }
+    }
+
+    @Override
+    public Iterable<ConfigMap> getChildren() {
+        return Arrays.asList(entries, collections);
+    }
+
+    boolean isEmpty() {
+        return entries.isEmpty() && collections.isEmpty();
+    }
+
+}

+ 7 - 3
src/main/java/me/lortseam/completeconfig/gui/cloth/ClothConfigScreenBuilder.java

@@ -15,9 +15,11 @@ import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.fabricmc.loader.api.FabricLoader;
 import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.text.StringVisitable;
 import net.minecraft.text.TranslatableText;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.function.Supplier;
 
@@ -54,6 +56,7 @@ public final class ClothConfigScreenBuilder extends ConfigScreenBuilder {
         }
         for(Collection collection : config.getCollections()) {
             ConfigCategory category = builder.getOrCreateCategory(collection.getText());
+            category.setDescription(() -> collection.getTooltipTranslation().map(lines -> Arrays.stream(lines).map(line -> (StringVisitable) line).toArray(StringVisitable[]::new)));
             for (AbstractConfigListEntry<?> entry : buildCollection(collection)) {
                 category.addEntry(entry);
             }
@@ -72,9 +75,10 @@ public final class ClothConfigScreenBuilder extends ConfigScreenBuilder {
         for (Entry<?> entry : collection.getEntries()) {
             collectionGui.add(buildEntry(entry));
         }
-        for (Collection c : collection.getCollections()) {
-            SubCategoryBuilder subBuilder = ConfigEntryBuilder.create().startSubCategory(c.getText());
-            subBuilder.addAll(buildCollection(c));
+        for (Collection subCollection : collection.getCollections()) {
+            SubCategoryBuilder subBuilder = ConfigEntryBuilder.create().startSubCategory(subCollection.getText());
+            subBuilder.setTooltip(subCollection.getTooltipTranslation());
+            subBuilder.addAll(buildCollection(subCollection));
             collectionGui.add(subBuilder.build());
         }
         return collectionGui;