Exemple #1
0
        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;
 }
Exemple #5
0
        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);
            }
        }