Example #1
0
        public static bool DrawRecursive(ref object target, BaseGUI gui, int id, UnityObject unityTarget, params string[] memberNames)
        {
            List <MemberInfo> members;
            var targetType = target.GetType();

            if (memberNames.IsNullOrEmpty())
            {
                members = VFWVisibilityLogic.CachedGetVisibleMembers(targetType);
            }
            else
            {
                members = new List <MemberInfo>();
                for (int i = 0; i < memberNames.Length; i++)
                {
                    var name   = memberNames[i];
                    var member = ReflectionHelper.CachedGetMember(targetType, name);
                    if (member == null)
                    {
                        LogFormat("RecursiveDrawer: Couldn't find member {0} in {1}", name, targetType.Name);
                        continue;
                    }
                    if (VFWVisibilityLogic.IsVisibleMember(member))
                    {
                        members.Add(member);
                    }
                }
            }

            if (members.Count == 0)
            {
                gui.HelpBox("Object doesn't have any visible members");
                return(false);
            }

            bool changed = false;

            using (gui.Indent())
            {
                for (int i = 0; i < members.Count; i++)
                {
                    MemberInfo   member = members[i];
                    EditorMember em;
                    changed |= gui.Member(member, target, unityTarget, id, false, out em);
                    target   = em.RawTarget;
                }
            }

            return(changed);
        }
Example #2
0
        /// <summary>
        /// Fetches visible members in the inspected target object and assigns them to their corresponding categories
        /// </summary>
        private void Initialize()
        {
            OnBeforeInitialized();

            // fetch visible members
            _visibleMembers = VFWVisibilityLogic.CachedGetVisibleMembers(targetType).ToList();

            // allocate categories
            _categories = new List <MembersCategory>();

            var multiple    = targetType.GetCustomAttribute <DefineCategoriesAttribute>(true);
            var definitions = targetType.GetCustomAttributes <DefineCategoryAttribute>(true);

            if (multiple != null)
            {
                definitions = definitions.Concat(multiple.names.Select(n => new DefineCategoryAttribute(n, 1000)));
            }

            Func <string, string[]> ParseCategoryPath = fullPath =>
            {
                int      nPaths = fullPath.Split('/').Length;
                string[] result = new string[nPaths];
                for (int i = 0, index = -1; i < nPaths - 1; i++)
                {
                    index     = fullPath.IndexOf('/', index + 1);
                    result[i] = fullPath.Substring(0, index);
                }
                result[nPaths - 1] = fullPath;
                return(result);
            };

            // Order by exclusivity
            var defs = from d in definitions
                       let paths = ParseCategoryPath(d.FullPath)
                                   orderby !d.Exclusive
                                   select new { def = d, paths };

            // Parse paths and resolve definitions
            var resolver = new CategoryDefinitionResolver();
            var lookup   = new Dictionary <string, MembersCategory>();

            foreach (var x in defs)
            {
                var paths = x.paths;
                var d     = x.def;

                MembersCategory parent = null;

                for (int i = 0; i < paths.Length; i++)
                {
                    var path = paths[i];

                    var current = (parent == null ?  _categories :
                                   parent.NestedCategories).FirstOrDefault(c => c.FullPath == path);

                    if (current == null)
                    {
                        current = new MembersCategory(path, d.DisplayOrder, id);
                        if (i == 0)
                        {
                            _categories.Add(current);
                        }
                        if (parent != null)
                        {
                            parent.NestedCategories.Add(current);
                        }
                    }
                    lookup[path] = current;
                    parent       = current;
                }

                var last = lookup[paths.Last()];
                last.ForceExpand      = d.ForceExpand;
                last.AlwaysHideHeader = d.AlwaysHideHeader;
                resolver.Resolve(_visibleMembers, d).Foreach(last.Members.Add);

                lookup.Clear();
                parent.Members = parent.Members.OrderBy <MemberInfo, float>(VFWVisibilityLogic.GetMemberDisplayOrder).ToList();
            }

            // filter out empty categories
            _categories = _categories.Where(x => x.NestedCategories.Count > 0 || x.Members.Count > 0)
                          .OrderBy(x => x.DisplayOrder)
                          .ToList();

            for (int i = 0; i < _categories.Count; i++)
            {
                var c = _categories[i];
                c.RemoveEmptyNestedCategories();
            }

            var displayKey   = RuntimeHelper.CombineHashCodes(id, "display");
            var displayValue = prefs.Ints.ValueOrDefault(displayKey, -1);
            var vfwSettings  = VFWSettings.GetInstance();

            _display = displayValue == -1 ? vfwSettings.DefaultDisplay : (CategoryDisplay)displayValue;
            prefs.Ints[displayKey] = (int)_display;

            var spacingKey = RuntimeHelper.CombineHashCodes(id, "spacing");

            _spacing = prefs.Ints.ValueOrDefault(spacingKey, vfwSettings.DefaultSpacing);
            prefs.Ints[spacingKey] = _spacing;

            var field = targetType.GetAllMembers(typeof(MonoBehaviour), Flags.InstancePrivate)
                        .FirstOrDefault(m => m.Name == "_serializationData");

            if (field == null)
            {
                throw new vMemberNotFound(targetType, "_serializationData");
            }

            _serializationData = EditorMember.WrapMember(field, target, target, id);

            field = targetType.GetField("dbg", Flags.InstanceAnyVisibility);
            if (field == null)
            {
                throw new vMemberNotFound(targetType, "dbg");
            }

            _debug = EditorMember.WrapMember(field, target, target, id);

            OnAfterInitialized();
        }