private void DataBind() { Clear(); Dictionary <string, MenuItemInfo> pathToItem = new Dictionary <string, MenuItemInfo>(); Dictionary <string, List <MenuItemInfo> > pathToChildren = new Dictionary <string, List <MenuItemInfo> >(); if (m_items != null) { for (int i = 0; i < m_items.Length; ++i) { MenuItemInfo menuItemInfo = m_items[i]; if (string.IsNullOrEmpty(menuItemInfo.Path) || !menuItemInfo.IsVisible) { continue; } menuItemInfo.Path = menuItemInfo.Path.Replace("\\", "/"); string[] pathParts = menuItemInfo.Path.Split('/'); if (pathParts.Length == m_depth + 1) { if (string.IsNullOrEmpty(menuItemInfo.Text)) { menuItemInfo.Text = pathParts[m_depth]; } pathToItem[pathParts[m_depth]] = menuItemInfo; } else { string path = string.Join("/", pathParts, 0, m_depth + 1); List <MenuItemInfo> childrenList; if (!pathToChildren.TryGetValue(path, out childrenList)) { childrenList = new List <MenuItemInfo>(); pathToChildren.Add(path, childrenList); } if (!pathToItem.ContainsKey(pathParts[m_depth])) { pathToItem[pathParts[m_depth]] = new MenuItemInfo { Text = pathParts[m_depth], Path = path }; } if (string.IsNullOrEmpty(menuItemInfo.Text)) { menuItemInfo.Text = pathParts[m_depth + 1]; } childrenList.Add(menuItemInfo); } } } foreach (MenuItemInfo menuItemInfo in pathToItem.Values) { MenuItem menuItem = Instantiate(m_menuItemPrefab, m_panel, false); menuItem.name = "MenuItem"; menuItem.Depth = Depth + 1; menuItem.Root = m_root; List <MenuItemInfo> childrenList; if (pathToChildren.TryGetValue(menuItemInfo.Path, out childrenList)) { menuItem.Children = childrenList.ToArray(); } menuItem.Item = menuItemInfo; } }
private void Awake() { List <Assembly> assemblies = new List <Assembly>(); foreach (string assemblyName in BHRoot.Assemblies) { var asName = new AssemblyName(); asName.Name = assemblyName; Assembly asm = Assembly.Load(asName); if (asm == null) { Debug.LogWarning("Unable to load " + assemblyName); continue; } assemblies.Add(asm); } if (m_menuPanel == null) { m_menuPanel = gameObject; } if (m_topMenu == null) { m_topMenu = gameObject; } if (m_menuButtonPrefab == null) { Debug.LogError("Set Menu Button Prefab"); return; } if (m_menuPrefab == null) { Debug.LogError("Set Menu Prefab"); return; } bool wasButtonPrefabActive = m_menuButtonPrefab.gameObject.activeSelf; bool wasMenuPrefabActive = m_menuPrefab.gameObject.activeSelf; Dictionary <string, Menu> menuDictionary = new Dictionary <string, Menu>(); Dictionary <string, List <MenuItemWithPriority> > menuItemsDictionary = new Dictionary <string, List <MenuItemWithPriority> >(); Menu[] menus = m_menuPanel.GetComponentsInChildren <Menu>(true); for (int i = 0; i < menus.Length; ++i) { if (!menuDictionary.ContainsKey(menus[i].name)) { menuDictionary.Add(menus[i].name, menus[i]); if (menus[i].Items != null) { List <MenuItemWithPriority> menuItemsWithPriority = new List <MenuItemWithPriority>(); for (int priority = 0; priority < menus[i].Items.Length; ++priority) { MenuItemInfo menuItemInfo = menus[i].Items[priority]; menuItemsWithPriority.Add(new MenuItemWithPriority(menuItemInfo, priority)); } menuItemsDictionary.Add(menus[i].name, menuItemsWithPriority); } else { menuItemsDictionary.Add(menus[i].name, new List <MenuItemWithPriority>()); } } } Type[] menuDefinitions = assemblies.SelectMany(asm => asm.GetTypesWithAttribute(typeof(MenuDefinitionAttribute))).OrderBy(kvp => ((MenuDefinitionAttribute)kvp.Value).Order).Select(kvp => kvp.Key).ToArray(); foreach (Type menuDef in menuDefinitions) { MethodInfo[] methods = menuDef.GetMethods(BindingFlags.Static | BindingFlags.Public); for (int i = 0; i < methods.Length; ++i) { MethodInfo mi = methods[i]; MenuCommandAttribute cmd = (MenuCommandAttribute)mi.GetCustomAttributes(typeof(MenuCommandAttribute), true).FirstOrDefault(); if (cmd == null || string.IsNullOrEmpty(cmd.Path)) { continue; } if (cmd.RequiresInstance) { if (FindObjectOfType(menuDef) == null) { continue; } } string[] pathParts = cmd.Path.Split('/'); if (pathParts.Length < 1) { continue; } string menuName = pathParts[0]; if (!menuDictionary.ContainsKey(menuName)) { MainMenuButton btn = _CreateMenu(menuName); menuDictionary.Add(menuName, btn.Menu); menuItemsDictionary.Add(menuName, new List <MenuItemWithPriority>()); } if (pathParts.Length == 1) { if (cmd.Hide) { menuItemsDictionary[menuName].Clear(); } } if (pathParts.Length < 2) { continue; } string path = string.Join("/", pathParts.Skip(1)); List <MenuItemWithPriority> menuItems = menuItemsDictionary[menuName]; MenuItemWithPriority menuItem = menuItems.Where(item => item.Info.Path == path).FirstOrDefault(); if (menuItem == null) { menuItem = new MenuItemWithPriority(); menuItems.Add(menuItem); } menuItem.Info.Path = string.Join("/", pathParts.Skip(1)); menuItem.Info.Icon = !string.IsNullOrEmpty(cmd.IconPath) ? Resources.Load <Sprite>(cmd.IconPath) : null; menuItem.Info.Text = pathParts.Last(); if (cmd.Validate) { Func <bool> validate = (Func <bool>)Delegate.CreateDelegate(typeof(Func <bool>), mi, false); if (validate == null) { Debug.LogWarning("method signature is invalid. bool Func() is expected. " + string.Join("/", pathParts)); } else { menuItem.Info.Validate = new MenuItemValidationEvent(); menuItem.Info.Validate.AddListener(new UnityAction <MenuItemValidationArgs>(args => args.IsValid = validate())); } } else { Action action = (Action)Delegate.CreateDelegate(typeof(Action), mi, false); if (action == null) { Debug.LogWarning("method signature is invalid. void Action() is expected. " + string.Join("/", pathParts)); } else { menuItem.Info.Action = new MenuItemEvent(); menuItem.Info.Action.AddListener(new UnityAction <string>(args => action())); } } if (cmd.Hide) { menuItems.Remove(menuItem); } menuItem.Priority = cmd.Priority; } m_menuPrefab.gameObject.SetActive(wasMenuPrefabActive); m_menuButtonPrefab.gameObject.SetActive(wasButtonPrefabActive); } foreach (KeyValuePair <string, List <MenuItemWithPriority> > kvp in menuItemsDictionary) { menuDictionary[kvp.Key].SetMenuItems(kvp.Value.OrderBy(m => m.Priority).Select(m => m.Info).ToArray(), false); } }
public MenuItemWithPriority(MenuItemInfo menuItemInfo, int priority) { Info = menuItemInfo; Priority = priority; }
public MenuItemWithPriority() { Info = new MenuItemInfo(); Priority = int.MaxValue; }
private void Awake() { var asName = new AssemblyName(); asName.Name = "Assembly-CSharp"; Assembly csAssembly = Assembly.Load(asName); if (csAssembly == null) { Debug.LogWarning("Unable to load Assembly-CSharp"); return; } if (m_menuPanel == null) { m_menuPanel = gameObject; } if (m_topMenu == null) { m_topMenu = gameObject; } if (m_menuButtonPrefab == null) { Debug.LogError("Set Menu Button Prefab"); return; } if (m_menuPrefab == null) { Debug.LogError("Set Menu Prefab"); return; } bool wasButtonPrefabActive = m_menuButtonPrefab.gameObject.activeSelf; bool wasMenuPrefabActive = m_menuPrefab.gameObject.activeSelf; Dictionary <string, Menu> menuDictionary = new Dictionary <string, Menu>(); Dictionary <string, List <MenuItemInfo> > menuItemsDictionary = new Dictionary <string, List <MenuItemInfo> >(); Menu[] menus = m_menuPanel.GetComponentsInChildren <Menu>(true); for (int i = 0; i < menus.Length; ++i) { if (!menuDictionary.ContainsKey(menus[i].name)) { menuDictionary.Add(menus[i].name, menus[i]); if (menus[i].Items != null) { menuItemsDictionary.Add(menus[i].name, menus[i].Items.ToList()); } else { menuItemsDictionary.Add(menus[i].name, new List <MenuItemInfo>()); } } } Type[] menuDefinitions = csAssembly.GetTypesWithAttribute(typeof(MenuDefinitionAttribute)).ToArray(); foreach (Type menuDef in menuDefinitions) { MethodInfo[] methods = menuDef.GetMethods(BindingFlags.Static | BindingFlags.Public); for (int i = 0; i < methods.Length; ++i) { MethodInfo mi = methods[i]; MenuCommandAttribute cmd = (MenuCommandAttribute)mi.GetCustomAttributes(typeof(MenuCommandAttribute), true).FirstOrDefault(); if (string.IsNullOrEmpty(cmd.Path)) { continue; } string[] pathParts = cmd.Path.Split('/'); if (pathParts.Length < 2) { continue; } string menuName = pathParts[0]; Menu menu; if (!menuDictionary.ContainsKey(menuName)) { m_menuButtonPrefab.gameObject.SetActive(false); m_menuPrefab.gameObject.SetActive(false); menu = Instantiate(m_menuPrefab, m_menuPanel.transform, false); menu.Items = null; MainMenuButton btn = Instantiate(m_menuButtonPrefab, m_topMenu.transform, false); btn.name = menuName; btn.Menu = menu; Text txt = btn.GetComponentInChildren <Text>(true); if (txt != null) { txt.text = menuName; } btn.gameObject.SetActive(true); menuDictionary.Add(menuName, menu); menuItemsDictionary.Add(menuName, new List <MenuItemInfo>()); } else { menu = menuDictionary[menuName]; } string path = string.Join("/", pathParts.Skip(1)); List <MenuItemInfo> menuItems = menuItemsDictionary[menuName]; MenuItemInfo menuItem = menuItems.Where(item => item.Path == path).FirstOrDefault(); if (menuItem == null) { menuItem = new MenuItemInfo(); menuItems.Add(menuItem); } menuItem.Path = string.Join("/", pathParts.Skip(1)); menuItem.Icon = !string.IsNullOrEmpty(cmd.IconPath) ? Resources.Load <Sprite>(cmd.IconPath) : null; menuItem.Text = pathParts.Last(); if (cmd.Validate) { Func <bool> validate = (Func <bool>)Delegate.CreateDelegate(typeof(Func <bool>), mi, false); if (validate == null) { Debug.LogWarning("method signature is invalid. bool Func() is expected. " + string.Join("/", pathParts)); } else { menuItem.Validate = new MenuItemValidationEvent(); menuItem.Validate.AddListener(new UnityAction <MenuItemValidationArgs>(args => args.IsValid = validate())); } } else { Action action = (Action)Delegate.CreateDelegate(typeof(Action), mi, false); if (action == null) { Debug.LogWarning("method signature is invalid. void Action() is expected. " + string.Join("/", pathParts)); } else { menuItem.Action = new MenuItemEvent(); menuItem.Action.AddListener(new UnityAction <string>(args => action())); } } if (cmd.Hide) { menuItems.Remove(menuItem); } } m_menuPrefab.gameObject.SetActive(wasMenuPrefabActive); m_menuButtonPrefab.gameObject.SetActive(wasButtonPrefabActive); } foreach (KeyValuePair <string, List <MenuItemInfo> > kvp in menuItemsDictionary) { menuDictionary[kvp.Key].SetMenuItems(kvp.Value.ToArray(), false); } }