feat(menustyling) remove other styling before applying

This commit is contained in:
Lillith Rose 2026-01-07 16:43:34 -05:00
parent 1bf6887bf0
commit a49d2d74e6
2 changed files with 51 additions and 14 deletions

View file

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;
using gay.lilyy.MenuStyling;
using nadena.dev.ndmf;
using nadena.dev.ndmf.vrchat;
@ -22,17 +23,26 @@ namespace gay.lilyy.MenuStyling
if (obj != null)
{
var descriptor = ctx.VRChatAvatarDescriptor();
descriptor.expressionsMenu = DuplicateMenu(descriptor.expressionsMenu);
WalkMenu(obj, descriptor.expressionsMenu);
var processedMenus = new HashSet<VRCExpressionsMenu>();
descriptor.expressionsMenu = DuplicateMenu(descriptor.expressionsMenu, processedMenus);
var walkProcessedMenus = new HashSet<VRCExpressionsMenu>();
WalkMenu(obj, descriptor.expressionsMenu, walkProcessedMenus);
Object.DestroyImmediate(obj);
}
});
}
private VRCExpressionsMenu DuplicateMenu(VRCExpressionsMenu menu)
private VRCExpressionsMenu DuplicateMenu(VRCExpressionsMenu menu, HashSet<VRCExpressionsMenu> processedMenus)
{
if (menu == null) return null;
// Prevent circular references - if we've already processed this menu, return null to break the cycle
if (processedMenus.Contains(menu))
{
return null;
}
processedMenus.Add(menu);
var newMenu = ScriptableObject.CreateInstance<VRCExpressionsMenu>();
newMenu.controls = new List<Control>();
@ -44,7 +54,7 @@ namespace gay.lilyy.MenuStyling
type = control.type,
icon = control.icon,
parameter = control.parameter,
subMenu = DuplicateMenu(control.subMenu),
subMenu = DuplicateMenu(control.subMenu, processedMenus),
value = control.value,
style = control.style,
labels = control.labels,
@ -56,24 +66,50 @@ namespace gay.lilyy.MenuStyling
return newMenu;
}
private void WalkMenu(MenuStylingConfig config, VRCExpressionsMenu menu)
private string StripTextMeshProTags(string text)
{
if (string.IsNullOrEmpty(text)) return text;
// Remove all TextMeshPro/rich text tags
// Pattern matches: <tag>, </tag>, <tag=value>, <tag="value">, <tag='value'>
text = Regex.Replace(text, @"<[^>]+>", "");
return text;
}
private void WalkMenu(MenuStylingConfig config, VRCExpressionsMenu menu, HashSet<VRCExpressionsMenu> processedMenus)
{
if (menu == null) return;
// Prevent circular references
if (processedMenus.Contains(menu))
{
return;
}
processedMenus.Add(menu);
foreach (var child in menu.controls)
{
if (child.name != " " && child.name != "" && child.name != null) {
if (!child.name.StartsWith(config.Prefix))
{
child.name = config.Prefix + child.name;
}
if (!child.name.EndsWith(config.Suffix))
{
child.name += config.Suffix;
}
// Strip all TextMeshPro styling tags first if enabled
if (config.RemovePreexistingStyling)
{
child.name = StripTextMeshProTags(child.name);
}
if (!child.name.StartsWith(config.Prefix))
{
child.name = config.Prefix + child.name;
}
if (!child.name.EndsWith(config.Suffix))
{
child.name += config.Suffix;
}
}
if (child.type == Control.ControlType.SubMenu && child.subMenu != null)
{
WalkMenu(config, child.subMenu);
WalkMenu(config, child.subMenu, processedMenus);
}
}
}

View file

@ -8,5 +8,6 @@ namespace gay.lilyy.MenuStyling
{
public string Prefix = "<b><color=#c481d6>";
public string Suffix = "";
public bool RemovePreexistingStyling = true;
}
}