mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2025-04-24 13:29:01 +08:00
Menus added by MenuInstaller should also be displayed.
This commit is contained in:
parent
f2f9df229f
commit
260fdb44a7
@ -23,6 +23,12 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
set => _treeView.Avatar = value;
|
set => _treeView.Avatar = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ModularAvatarMenuInstaller Installer
|
||||||
|
{
|
||||||
|
get => _treeView.Installer;
|
||||||
|
set => _treeView.Installer = value;
|
||||||
|
}
|
||||||
|
|
||||||
public Action<VRCExpressionsMenu> OnMenuSelected = (menu) => { };
|
public Action<VRCExpressionsMenu> OnMenuSelected = (menu) => { };
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
@ -53,12 +59,13 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
_treeView.OnGUI(new Rect(0, 0, position.width, position.height));
|
_treeView.OnGUI(new Rect(0, 0, position.width, position.height));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Show(VRCAvatarDescriptor Avatar, Action<VRCExpressionsMenu> OnSelect)
|
internal static void Show(VRCAvatarDescriptor Avatar, ModularAvatarMenuInstaller Installer, Action<VRCExpressionsMenu> OnSelect)
|
||||||
{
|
{
|
||||||
var window = GetWindow<AvMenuTreeViewWindow>();
|
var window = GetWindow<AvMenuTreeViewWindow>();
|
||||||
window.titleContent = new GUIContent("Select menu");
|
window.titleContent = new GUIContent("Select menu");
|
||||||
|
|
||||||
window.Avatar = Avatar;
|
window.Avatar = Avatar;
|
||||||
|
window.Installer = Installer;
|
||||||
window.OnMenuSelected = OnSelect;
|
window.OnMenuSelected = OnSelect;
|
||||||
|
|
||||||
window.Show();
|
window.Show();
|
||||||
@ -79,6 +86,18 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ModularAvatarMenuInstaller _installer;
|
||||||
|
|
||||||
|
public ModularAvatarMenuInstaller Installer
|
||||||
|
{
|
||||||
|
get => _installer;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_installer = value;
|
||||||
|
Reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal Action<VRCExpressionsMenu> OnSelect = (menu) => { };
|
internal Action<VRCExpressionsMenu> OnSelect = (menu) => { };
|
||||||
internal Action OnDoubleclickSelect = () => { };
|
internal Action OnDoubleclickSelect = () => { };
|
||||||
|
|
||||||
@ -107,20 +126,19 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
this._menuItems.Clear();
|
this._menuItems.Clear();
|
||||||
this._visitedMenuStack.Clear();
|
this._visitedMenuStack.Clear();
|
||||||
|
|
||||||
if (Avatar.expressionsMenu == null) {
|
|
||||||
// TODO: nullの場合もツリーを表示できるように(Installerがあれば子もあるので)
|
|
||||||
return new TreeViewItem(0, -1, "No menu");
|
|
||||||
}
|
|
||||||
|
|
||||||
_menuTree = new MenuTree(Avatar);
|
_menuTree = new MenuTree(Avatar);
|
||||||
_menuTree.AvatarsMenuMapping();
|
_menuTree.AvatarsMenuMapping();
|
||||||
|
foreach (ModularAvatarMenuInstaller installer in this.Avatar.gameObject.GetComponentsInChildren<ModularAvatarMenuInstaller>()) {
|
||||||
|
if (installer == Installer) continue;
|
||||||
|
this._menuTree.MappingMenuInstaller(installer);
|
||||||
|
}
|
||||||
|
|
||||||
var root = new TreeViewItem(-1, -1, "<root>");
|
var root = new TreeViewItem(-1, -1, "<root>");
|
||||||
List<TreeViewItem> treeItems = new List<TreeViewItem> {
|
List<TreeViewItem> treeItems = new List<TreeViewItem> {
|
||||||
new TreeViewItem {
|
new TreeViewItem {
|
||||||
id = 0,
|
id = 0,
|
||||||
depth = 0,
|
depth = 0,
|
||||||
displayName = $"{Avatar.gameObject.name} ({Avatar.expressionsMenu.name})"
|
displayName = $"{Avatar.gameObject.name} ({(Avatar.expressionsMenu == null ? "None" : Avatar.expressionsMenu.name)})"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this._menuItems.Add(Avatar.expressionsMenu);
|
this._menuItems.Add(Avatar.expressionsMenu);
|
||||||
@ -132,19 +150,19 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void TraverseMenu(int depth, List<TreeViewItem> items, VRCExpressionsMenu menu) {
|
private void TraverseMenu(int depth, List<TreeViewItem> items, VRCExpressionsMenu menu) {
|
||||||
IEnumerable<VRCExpressionsMenu> children = this._menuTree.GetChildren(menu)
|
IEnumerable<KeyValuePair<string, VRCExpressionsMenu>> children = this._menuTree.GetChildren(menu)
|
||||||
.Where(child => !this._visitedMenuStack.Contains(child));
|
.Where(child => !this._visitedMenuStack.Contains(child.Value));
|
||||||
foreach (VRCExpressionsMenu child in children) {
|
foreach (KeyValuePair<string, VRCExpressionsMenu> child in children) {
|
||||||
items.Add(
|
items.Add(
|
||||||
new TreeViewItem {
|
new TreeViewItem {
|
||||||
id = items.Count,
|
id = items.Count,
|
||||||
depth = depth,
|
depth = depth,
|
||||||
displayName = $"{ /*control.name*/null} ({child.name})" // TODO: サブメニュー名を取ってこれるように
|
displayName = $"{child.Key} ({child.Value.name})"
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
this._menuItems.Add(child);
|
this._menuItems.Add(child.Value);
|
||||||
this._visitedMenuStack.Push(child);
|
this._visitedMenuStack.Push(child.Value);
|
||||||
this.TraverseMenu(depth + 1, items, child);
|
this.TraverseMenu(depth + 1, items, child.Value);
|
||||||
this._visitedMenuStack.Pop();
|
this._visitedMenuStack.Pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
{
|
{
|
||||||
if (installTargetType == InstallTargetType.VRCExpressionMenu)
|
if (installTargetType == InstallTargetType.VRCExpressionMenu)
|
||||||
{
|
{
|
||||||
AvMenuTreeViewWindow.Show(avatar, menu =>
|
AvMenuTreeViewWindow.Show(avatar, _installer, menu =>
|
||||||
{
|
{
|
||||||
installTargetProperty.objectReferenceValue = menu;
|
installTargetProperty.objectReferenceValue = menu;
|
||||||
serializedObject.ApplyModifiedProperties();
|
serializedObject.ApplyModifiedProperties();
|
||||||
|
@ -48,7 +48,7 @@ namespace nadena.dev.modular_avatar.core.editor {
|
|||||||
VRCAvatarDescriptor avatar = RuntimeUtil.FindAvatarInParents(this._creator.transform);
|
VRCAvatarDescriptor avatar = RuntimeUtil.FindAvatarInParents(this._creator.transform);
|
||||||
if (avatar != null && GUILayout.Button(Localization.G("menuinstall.selectmenu"))) {
|
if (avatar != null && GUILayout.Button(Localization.G("menuinstall.selectmenu"))) {
|
||||||
if (installTargetType == InstallTargetType.VRCExpressionMenu) {
|
if (installTargetType == InstallTargetType.VRCExpressionMenu) {
|
||||||
AvMenuTreeViewWindow.Show(avatar, menu => {
|
AvMenuTreeViewWindow.Show(avatar, null, menu => {
|
||||||
installTargetProperty.objectReferenceValue = menu;
|
installTargetProperty.objectReferenceValue = menu;
|
||||||
serializedObject.ApplyModifiedProperties();
|
serializedObject.ApplyModifiedProperties();
|
||||||
});
|
});
|
||||||
|
@ -11,14 +11,14 @@ namespace nadena.dev.modular_avatar.core.editor {
|
|||||||
public class MenuTree {
|
public class MenuTree {
|
||||||
private readonly VRCExpressionsMenu _rootMenu;
|
private readonly VRCExpressionsMenu _rootMenu;
|
||||||
private readonly HashSet<VRCExpressionsMenu> _included;
|
private readonly HashSet<VRCExpressionsMenu> _included;
|
||||||
private readonly Dictionary<VRCExpressionsMenu, List<VRCExpressionsMenu>> _childrenMap;
|
private readonly Dictionary<VRCExpressionsMenu, List<KeyValuePair<string, VRCExpressionsMenu>>> _childrenMap;
|
||||||
|
|
||||||
private readonly Dictionary<VRCExpressionsMenu, ImmutableArray<VRCExpressionsMenu>> _flashedChildrenMap;
|
private readonly Dictionary<VRCExpressionsMenu, ImmutableArray<VRCExpressionsMenu>> _flashedChildrenMap;
|
||||||
|
|
||||||
public MenuTree(VRCAvatarDescriptor descriptor) {
|
public MenuTree(VRCAvatarDescriptor descriptor) {
|
||||||
this._rootMenu = descriptor.expressionsMenu;
|
this._rootMenu = descriptor.expressionsMenu;
|
||||||
this._included = new HashSet<VRCExpressionsMenu>();
|
this._included = new HashSet<VRCExpressionsMenu>();
|
||||||
this._childrenMap = new Dictionary<VRCExpressionsMenu, List<VRCExpressionsMenu>>();
|
this._childrenMap = new Dictionary<VRCExpressionsMenu, List<KeyValuePair<string, VRCExpressionsMenu>>>();
|
||||||
|
|
||||||
if (this._rootMenu == null) {
|
if (this._rootMenu == null) {
|
||||||
this._rootMenu = ScriptableObject.CreateInstance<VRCExpressionsMenu>();
|
this._rootMenu = ScriptableObject.CreateInstance<VRCExpressionsMenu>();
|
||||||
@ -32,17 +32,19 @@ namespace nadena.dev.modular_avatar.core.editor {
|
|||||||
this.MappingMenu(this._rootMenu);
|
this.MappingMenu(this._rootMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddMenuInstaller(ModularAvatarMenuInstaller installer) {
|
public void MappingMenuInstaller(ModularAvatarMenuInstaller installer) {
|
||||||
if (installer.menuToAppend == null) return;
|
if (installer.menuToAppend == null) return;
|
||||||
VRCExpressionsMenu parent = installer.installTargetMenu;
|
VRCExpressionsMenu parent = installer.installTargetMenu;
|
||||||
if (parent == null) parent = this._rootMenu;
|
if (parent == null) parent = this._rootMenu;
|
||||||
this.MappingMenu(installer.menuToAppend, parent);
|
this.MappingMenu(installer.menuToAppend, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<VRCExpressionsMenu> GetChildren(VRCExpressionsMenu parent) {
|
public IEnumerable<KeyValuePair<string, VRCExpressionsMenu>> GetChildren(VRCExpressionsMenu parent) {
|
||||||
// TODO: ライブラリとするのであれば、複製したリスト or ImmutableArray,を返すのが好ましい
|
// TODO: ライブラリとするのであれば、複製したリスト or ImmutableArray,を返すのが好ましい
|
||||||
if (parent == null) parent = this._rootMenu;
|
if (parent == null) parent = this._rootMenu;
|
||||||
return this._childrenMap.TryGetValue(parent, out List<VRCExpressionsMenu> children) ? children : Enumerable.Empty<VRCExpressionsMenu>();
|
return this._childrenMap.TryGetValue(parent, out List<KeyValuePair<string, VRCExpressionsMenu>> children)
|
||||||
|
? children
|
||||||
|
: Enumerable.Empty<KeyValuePair<string, VRCExpressionsMenu>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MappingMenu(VRCExpressionsMenu root, VRCExpressionsMenu customParent = null) {
|
private void MappingMenu(VRCExpressionsMenu root, VRCExpressionsMenu customParent = null) {
|
||||||
@ -51,29 +53,30 @@ namespace nadena.dev.modular_avatar.core.editor {
|
|||||||
|
|
||||||
while (queue.Count > 0) {
|
while (queue.Count > 0) {
|
||||||
VRCExpressionsMenu parent = queue.Dequeue();
|
VRCExpressionsMenu parent = queue.Dequeue();
|
||||||
IEnumerable<VRCExpressionsMenu> subMenus = GetSubMenus(parent);
|
IEnumerable<KeyValuePair<string, VRCExpressionsMenu>> subMenus = GetSubMenus(parent);
|
||||||
if (customParent != null) {
|
if (customParent != null) {
|
||||||
parent = customParent;
|
parent = customParent;
|
||||||
customParent = null;
|
customParent = null;
|
||||||
}
|
}
|
||||||
foreach (VRCExpressionsMenu subMenu in subMenus) {
|
|
||||||
if (!this._childrenMap.TryGetValue(parent, out List<VRCExpressionsMenu> children)) {
|
foreach (KeyValuePair<string, VRCExpressionsMenu> subMenu in subMenus) {
|
||||||
children = new List<VRCExpressionsMenu>();
|
if (!this._childrenMap.TryGetValue(parent, out List<KeyValuePair<string, VRCExpressionsMenu>> children)) {
|
||||||
|
children = new List<KeyValuePair<string, VRCExpressionsMenu>>();
|
||||||
this._childrenMap[parent] = children;
|
this._childrenMap[parent] = children;
|
||||||
}
|
}
|
||||||
|
|
||||||
children.Add(subMenu);
|
children.Add(subMenu);
|
||||||
if (this._included.Contains(subMenu)) continue;
|
if (this._included.Contains(subMenu.Value)) continue;
|
||||||
queue.Enqueue(subMenu);
|
queue.Enqueue(subMenu.Value);
|
||||||
this._included.Add(subMenu);
|
this._included.Add(subMenu.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<VRCExpressionsMenu> GetSubMenus(VRCExpressionsMenu expressionsMenu) {
|
private static IEnumerable<KeyValuePair<string, VRCExpressionsMenu>> GetSubMenus(VRCExpressionsMenu expressionsMenu) {
|
||||||
return expressionsMenu.controls
|
return expressionsMenu.controls
|
||||||
.Where(control => control.type == ControlType.SubMenu && control.subMenu != null)
|
.Where(control => control.type == ControlType.SubMenu && control.subMenu != null)
|
||||||
.Select(control => control.subMenu);
|
.Select(control => new KeyValuePair<string, VRCExpressionsMenu>(control.name, control.subMenu));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user