diff --git a/.gitignore b/.gitignore index f427fdd2..c2fa78c1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ eclipse run libs media +__pycache__ +*.pyc classes/ .architectury-transformer/ fabric/fabricloader.log diff --git a/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index 3801b310..98806da7 100644 --- a/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -128,21 +128,8 @@ public class ModernFixEarlyConfig { mixinsMissingMods.put(mixinClassName, requiredModId); else if(isClientOnly && !ModernFixPlatformHooks.INSTANCE.isClient()) mixinsMissingMods.put(mixinClassName, "[not client]"); - List mixinOptionNames = dotSplitter.splitToList(mixinClassName); - StringBuilder optionBuilder = new StringBuilder(mixinClassName.length()); - optionBuilder.append("mixin"); - // mixin.core, mixin.safety can be top-level, everything else must have a subcategory - boolean allowTopLevel; - if(mixinOptionNames.size() > 0) - allowTopLevel = mixinOptionNames.get(0).equals("core") || mixinOptionNames.get(0).equals("safety"); - else - allowTopLevel = false; - for(int i = 0; i < mixinOptionNames.size() - 1; i++) { - optionBuilder.append('.'); - optionBuilder.append(mixinOptionNames.get(i)); - if(i > 0 || allowTopLevel) - mixinOptions.add(optionBuilder.toString()); - } + String mixinCategoryName = "mixin." + mixinClassName.substring(0, mixinClassName.lastIndexOf('.')); + mixinOptions.add(mixinCategoryName); } } catch(IOException e) { ModernFix.LOGGER.error("Error scanning file " + mixinPath, e); @@ -198,6 +185,17 @@ public class ModernFixEarlyConfig { this.options.putIfAbsent(optionName, option); this.optionsByCategory.put(OptionCategories.getCategoryForOption(optionName), option); } + for(Map.Entry entry : this.options.entrySet()) { + int idx = entry.getKey().lastIndexOf('.'); + if(idx <= 0) + continue; + String potentialParentKey = entry.getKey().substring(0, idx); + Option potentialParent = this.options.get(potentialParentKey); + if(potentialParent != null) { + System.out.println(potentialParentKey + " -> " + entry.getKey()); + entry.getValue().setParent(potentialParent); + } + } // Defines the default rules which can be configured by the user or other mods. // You must manually add a rule for any new mixins not covered by an existing package rule. this.addMixinRule("launch.class_search_cache", true); diff --git a/common/src/main/java/org/embeddedt/modernfix/core/config/Option.java b/common/src/main/java/org/embeddedt/modernfix/core/config/Option.java index f370e8bc..6eac9434 100644 --- a/common/src/main/java/org/embeddedt/modernfix/core/config/Option.java +++ b/common/src/main/java/org/embeddedt/modernfix/core/config/Option.java @@ -11,6 +11,7 @@ public class Option { private Set modDefined = null; private boolean enabled; private boolean userDefined; + private Option parent = null; public Option(String name, boolean enabled, boolean userDefined) { this.name = name; @@ -37,10 +38,33 @@ public class Option { this.modDefined.add(modId); } + public void setParent(Option option) { + this.parent = option; + } + + public Option getParent() { + return this.parent; + } + + public int getDepth() { + if(this.parent == null) + return 0; + else + return this.parent.getDepth() + 1; + } + public boolean isEnabled() { return this.enabled; } + /** + * Checks if this option will effectively be disabled (regardless of its own status) + * by the parent rule being disabled. + */ + public boolean isEffectivelyDisabledByParent() { + return this.parent != null && (!this.parent.enabled || this.parent.isEffectivelyDisabledByParent()); + } + public boolean isOverridden() { return this.isUserDefined() || this.isModDefined(); } @@ -57,6 +81,13 @@ public class Option { return this.name; } + public String getSelfName() { + if(this.parent == null) + return this.name; + else + return this.name.substring(this.parent.getName().length() + 1); + } + public void clearModsDefiningValue() { this.modDefined = null; } diff --git a/common/src/main/java/org/embeddedt/modernfix/screen/OptionList.java b/common/src/main/java/org/embeddedt/modernfix/screen/OptionList.java index 3a9ecda3..f0ff2a21 100644 --- a/common/src/main/java/org/embeddedt/modernfix/screen/OptionList.java +++ b/common/src/main/java/org/embeddedt/modernfix/screen/OptionList.java @@ -20,10 +20,11 @@ import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; import java.io.IOException; import java.util.*; -import java.util.stream.Collectors; public class OptionList extends ContainerObjectSelectionList { - private final int maxNameWidth; + private int maxNameWidth = 0; + + private static final int DEPTH_OFFSET = 20; private static final Component OPTION_ON = new TranslatableComponent("modernfix.option.on").withStyle(ChatFormatting.GREEN); private static final Component OPTION_OFF = new TranslatableComponent("modernfix.option.off").withStyle(ChatFormatting.RED); @@ -32,22 +33,42 @@ public class OptionList extends ContainerObjectSelectionList { private ModernFixConfigScreen mainScreen; - private static MutableComponent getOptionComponent(String optionName) { - String friendlyKey = "modernfix.option.name." + optionName; - TextComponent baseComponent = new TextComponent(optionName); + private static MutableComponent getOptionComponent(Option option) { + String friendlyKey = "modernfix.option.name." + option.getName(); + TextComponent baseComponent = new TextComponent(option.getSelfName()); if(I18n.exists(friendlyKey)) return new TranslatableComponent(friendlyKey).withStyle(style -> style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, baseComponent))); else return baseComponent; } + public void updateOptionEntryStatuses() { + for(Entry e : this.children()) { + if(e instanceof OptionEntry) { + ((OptionEntry)e).updateStatus(); + } + } + } + + private final Set