예제 #1
0
        protected virtual Type GetDrawerTypeForMethod([NotNull] MethodInfo methodInfo)
        {
            Type drawerType;

            if (UseDrawerAttributeUtility.TryGetCustomDrawerForClassMember(this, methodInfo, out drawerType))
            {
                return(drawerType);
            }
            return(typeof(MethodDrawer));
        }
예제 #2
0
        public Type GetDrawerTypeForProperty(PropertyInfo propertyInfo)
        {
            Type drawerType;

            if (UseDrawerAttributeUtility.TryGetCustomDrawerForClassMember(this, propertyInfo, out drawerType))
            {
                return(drawerType);
            }

            if (propertyInfo.ShowInspectorViewableAsNormalField())
            {
                return(GetDrawerTypeForField(propertyInfo.PropertyType));
            }
            else
            {
                return(typeof(PropertyDrawer));
            }
        }
예제 #3
0
        public IDrawer GetForField([CanBeNull] object value, [NotNull] Type fieldType, [CanBeNull] LinkedMemberInfo memberInfo, [CanBeNull] IParentDrawer parent, [CanBeNull] GUIContent label, bool readOnly)
        {
                        #if DEV_MODE && PI_ASSERTATIONS
            Debug.Assert(fieldType != null, "CreateDefaultDrawer - null type!");
            Debug.Assert(memberInfo != null || value != null || fieldType.IsUnityObject() || Nullable.GetUnderlyingType(fieldType) != null, "CreateDefaultDrawer - both fieldInfo and value null!");
            if (memberInfo != null)
            {
                Debug.Assert(memberInfo.Type.IsAssignableFrom(fieldType), "CreateDefaultDrawer - memberInfo.Type " + StringUtils.ToString(memberInfo.Type) + " was not assignable from type " + StringUtils.ToString(fieldType) + "!");
            }
                        #endif

                        #if DEV_MODE && DEBUG_GET_FOR_FIELD
            Debug.Log("GetForField(" + StringUtils.ToStringSansNamespace(fieldType) + ", " + StringUtils.ToString(label) + ")...");
                        #endif

            Type drawerType;

            if (memberInfo != null && memberInfo.MemberInfo != null && UseDrawerAttributeUtility.TryGetCustomDrawerForClassMember(this, memberInfo.MemberInfo, out drawerType))
            {
                if (typeof(IPropertyDrawerDrawer).IsAssignableFrom(drawerType))
                {
                    var definingPropertyAttribute = GetAttributeThatDefinesDrawer(memberInfo, drawerType) as Attribute;
                    if (definingPropertyAttribute != null)
                    {
                        return(GetForPropertyDrawer(drawerType, definingPropertyAttribute, value, memberInfo, parent, label, readOnly));
                    }
                }
                return(GetForField(drawerType, value, fieldType, memberInfo, parent, label, readOnly));
            }

            if (memberInfo != null)
            {
                var attributes     = memberInfo.GetAttributes <PropertyAttribute>();
                int attributeCount = attributes.Length;
                if (attributeCount > 0)
                {
                    // E.g. List<string> => List<>.
                    Type fieldTypeOrGenericTypeDefinition;
                    if (fieldType.IsGenericType && !fieldType.IsGenericTypeDefinition)
                    {
                        fieldTypeOrGenericTypeDefinition = fieldType.GetGenericTypeDefinition();
                    }
                    else
                    {
                        fieldTypeOrGenericTypeDefinition = fieldType;
                    }

                    bool isCollection = memberInfo.IsCollection;

                    for (int n = 0; n < attributeCount; n++)
                    {
                        var fieldAttribute = attributes[n];

                        drawerType = GetDrawerTypeForPropertyAttribute(fieldAttribute.GetType(), fieldTypeOrGenericTypeDefinition);
                        if (drawerType != null)
                        {
                                                        #if DEV_MODE && (DEBUG_GET_FOR_FIELD || DEBUG_GET_FOR_PROPERTY_DRAWER)
                            Debug.Log("<color=green>PropertyDrawer drawer</color> for field " + StringUtils.ToStringSansNamespace(fieldType) + " and attribute " + fieldAttribute.GetType().Name + ": " + drawerType.Name);
                                                        #endif

                            return(GetForPropertyDrawer(drawerType, fieldAttribute, value, memberInfo, parent, label, readOnly));
                        }
                    }

                    for (int n = 0; n < attributeCount; n++)
                    {
                        var fieldAttribute = attributes[n];
                        for (var baseType = fieldType.BaseType; baseType != null; baseType = baseType.BaseType)
                        {
                            // E.g. List<string> => List<>.
                            if (baseType.IsGenericType && !baseType.IsGenericTypeDefinition)
                            {
                                fieldTypeOrGenericTypeDefinition = baseType.GetGenericTypeDefinition();
                            }
                            else
                            {
                                fieldTypeOrGenericTypeDefinition = baseType;
                            }

                            drawerType = GetDrawerTypeForPropertyAttribute(fieldAttribute.GetType(), fieldTypeOrGenericTypeDefinition);
                            if (drawerType != null)
                            {
                                                                #if DEV_MODE && (DEBUG_GET_FOR_FIELD || DEBUG_GET_FOR_PROPERTY_DRAWER)
                                Debug.Log("<color=green>PropertyDrawer drawer</color> for field " + fieldType.Name + " and attribute " + fieldAttribute.GetType().Name + ": " + drawerType.Name);
                                                                #endif

                                return(GetForPropertyDrawer(drawerType, fieldAttribute, value, memberInfo, parent, label, readOnly));
                            }
                        }
                    }
                }
            }

            drawerType = GetDrawerTypeForFieldWithPropertyDrawer(fieldType, memberInfo);
            if (drawerType != null)
            {
                                #if DEV_MODE && (DEBUG_GET_FOR_FIELD || DEBUG_GET_FOR_PROPERTY_DRAWER)
                Debug.Log("<color=green>PropertyDrawer drawer</color> for field " + StringUtils.ToStringSansNamespace(fieldType) + ": " + StringUtils.ToStringSansNamespace(drawerType));
                                #endif

                return(GetForPropertyDrawer(drawerType, null, value, memberInfo, parent, label, readOnly));
            }

            drawerType = GetDrawerTypeForField(fieldType);

                        #if DEV_MODE && DEBUG_GET_FOR_FIELD
            Debug.Log("<color=green>Field drawer</color> for field " + StringUtils.ToStringSansNamespace(fieldType) + ": " + StringUtils.ToStringSansNamespace(drawerType) + "\nmemberInfo=" + (memberInfo == null ? StringUtils.Null : memberInfo.LinkedMemberType.ToString()) + ", IsCollection=" + (memberInfo != null && memberInfo.IsCollection ? StringUtils.True : StringUtils.False) + ", Attributes=" + (memberInfo == null ? "n/a" : StringUtils.ToString(memberInfo.GetAttributes <PropertyAttribute>())));
                        #endif

            return(GetForField(drawerType, value, fieldType, memberInfo, parent, label, readOnly));
        }
예제 #4
0
        protected override void BuildDictionaries(DrawerProviderData drawersFor)
        {
            var drawerTypes = typeof(IDrawer).GetImplementingNonUnityObjectClassTypes(false);

            // Priority 1: plugin drawers providers
            var pluginProviders = DrawerFromPluginProvider.All;

            for (int n = pluginProviders.Length - 1; n >= 0; n--)
            {
                var provider = pluginProviders[n];

                if (!provider.IsActive)
                {
                                        #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_PLUGINS
                    Debug.Log("Skipping " + provider.GetType().Name + " because IsActive was " + StringUtils.False);
                                        #endif
                    continue;
                }

                try
                {
                    provider.AddFieldDrawer(drawersFor.fields);

                                        #if DEV_MODE && PI_ASSERTATIONS
                    AssertAllGUIInstructionTypesImplement(drawersFor.fields.Values, typeof(IFieldDrawer), provider, "AddFieldDrawer");
                                        #endif

                    provider.AddDecoratorDrawerDrawer(drawersFor.decoratorDrawers);

                                        #if DEV_MODE && PI_ASSERTATIONS
                    AssertAllGUIInstructionTypesImplement(drawersFor.decoratorDrawers.Values, typeof(IDecoratorDrawerDrawer), provider, "AddDecoratorDrawerDrawer");
                                        #endif

                    provider.AddPropertyDrawerDrawer(drawersFor.propertyDrawersByAttributeType, drawersFor.propertyDrawersByFieldType);

                                        #if DEV_MODE && PI_ASSERTATIONS
                    foreach (var dictionary in drawersFor.propertyDrawersByAttributeType.Values)
                    {
                        AssertAllGUIInstructionTypesImplement(dictionary.Values, typeof(IPropertyDrawerDrawer), provider, "AddPropertyDrawerDrawer");
                    }
                    AssertAllGUIInstructionTypesImplement(drawersFor.propertyDrawersByFieldType.Values, typeof(IPropertyDrawerDrawer), provider, "AddPropertyDrawerDrawer");
                                        #endif

                    provider.AddComponentDrawer(drawersFor.components);

                                        #if DEV_MODE && PI_ASSERTATIONS
                    AssertAllGUIInstructionTypesImplementOne(drawersFor.decoratorDrawers.Values, typeof(IEditorlessComponentDrawer), typeof(ICustomEditorComponentDrawer), provider, "AddComponentDrawer");
                                        #endif

                    provider.AddAssetDrawer(drawersFor.assets, drawersFor.assetsByExtension);

                                        #if DEV_MODE && PI_ASSERTATIONS
                    AssertAllGUIInstructionTypesImplementOne(drawersFor.assets.Values, typeof(IEditorlessAssetDrawer), typeof(ICustomEditorAssetDrawer), provider, "AddAssetDrawer");
                    AssertAllGUIInstructionTypesImplementOne(drawersFor.assetsByExtension.Values, typeof(IEditorlessAssetDrawer), typeof(ICustomEditorAssetDrawer), provider, "AddAssetDrawer");
                                        #endif
                }
                catch (Exception e)
                {
                    Debug.LogError(e);
                }
            }

            // Priority 2: non-fallback, non-inherited types
            BuildDictionariesForExactTypes(drawersFor, drawerTypes, false);

            // Priority 3: inherited types for non-fallback drawers
            BuildDictionariesForInheritedTypes(drawersFor, drawerTypes, false);

                        #if UNITY_EDITOR
            // Priority 4: PropertyDrawers and DecoratorDrawers and Editors outside of Unity namespace
            var propertyDrawers  = CustomEditorUtility.PropertyDrawersByType;
            var decoratorDrawers = CustomEditorUtility.DecoratorDrawersByType;
            var customEditors    = CustomEditorUtility.CustomEditorsByType;
            BuildDictionariesForPropertyDrawersInNonUnityNamespaces(drawersFor, propertyDrawers);
            BuildDictionariesForDecoratorDrawersInNonUnityNamespaces(drawersFor, decoratorDrawers);
            BuildDictionariesForCustomEditorsInNonUnityNamespaces(drawersFor, customEditors);
                        #endif

            //Priority 5: fallback, non-inherited types
            BuildDictionariesForExactTypes(drawersFor, drawerTypes, true);

            //Priority 6: fallback, inherited types
            BuildDictionariesForInheritedTypes(drawersFor, drawerTypes, true);

            // Make sure that GameObjects have some drawer
            if (drawersFor.gameObject == null)
            {
                drawersFor.gameObject = typeof(GameObjectDrawer);
            }

                        #if UNITY_EDITOR
            // Priority 4: PropertyDrawer and DecoratorDrawers and Editors inside of Unity namespace
            BuildDictionariesForPropertyDrawersInUnityNamespaces(drawersFor, propertyDrawers);
            BuildDictionariesForDecoratorDrawersInUnityNamespaces(drawersFor, decoratorDrawers);
            BuildDictionariesForCustomEditorsInUnityNamespaces(drawersFor, customEditors);
                        #endif

            // IUseDrawer overrides. This has highest priority, but it is done as the last step,
            // because IUseDrawer relies on getting the default drawers for different types.
            var useDrawerOverrides = UseDrawerAttributeUtility.GetCustomDrawersByClassType(this);

            foreach (var subjectAndDrawer in useDrawerOverrides)
            {
                var subjectType = subjectAndDrawer.Key;
                var drawerType  = subjectAndDrawer.Value;

                                #if DEV_MODE && PI_ASSERTATIONS
                Debug.Assert(subjectType != null);
                Debug.Assert(drawerType != null);
                Debug.Assert(typeof(IDrawer).IsAssignableFrom(drawerType));
                                #endif

                if (typeof(IComponentDrawer).IsAssignableFrom(drawerType))
                {
                                        #if DEV_MODE && PI_ASSERTATIONS
                    Debug.Assert(subjectType.IsComponent());
                                        #endif

                                        #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_COMPONENTS
                    Debug.Log(StringUtils.ToStringSansNamespace(subjectType) + " IUseDrawer override: " + StringUtils.ToStringSansNamespace(drawerType));
                                        #endif

                    drawersFor.components[subjectType] = drawerType;
                }
                else if (typeof(IAssetDrawer).IsAssignableFrom(drawerType))                // TO DO: support drawer by extension via additional parameters in DrawerForAttribute?
                {
                                        #if DEV_MODE && PI_ASSERTATIONS
                    Debug.Assert(subjectType.IsUnityObject() && !subjectType.IsComponent());
                                        #endif

                                        #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_ASSETS
                    Debug.Log(StringUtils.ToStringSansNamespace(subjectType) + " IUseDrawer override: " + StringUtils.ToStringSansNamespace(drawerType));
                                        #endif

                    drawersFor.assets[subjectType] = drawerType;
                }
                else if (typeof(IPropertyDrawerDrawer).IsAssignableFrom(drawerType))
                {
                                        #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_PROPERTY_DRAWERS
                    Debug.Log(StringUtils.ToStringSansNamespace(subjectType) + " IUseDrawer override: " + StringUtils.ToStringSansNamespace(drawerType));
                                        #endif

                    drawersFor.propertyDrawersByFieldType[subjectType] = drawerType;
                }
                else if (typeof(IDecoratorDrawerDrawer).IsAssignableFrom(drawerType))
                {
                                        #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_DECORATOR_DRAWERS
                    Debug.Log(StringUtils.ToStringSansNamespace(subjectType) + " IUseDrawer override: " + StringUtils.ToStringSansNamespace(drawerType));
                                        #endif

                    drawersFor.decoratorDrawers[subjectType] = drawerType;
                }
                else if (typeof(IFieldDrawer).IsAssignableFrom(drawerType))
                {
                                        #if DEV_MODE && DEBUG_BUILD_DICTIONARIES_FOR_FIELDS
                    Debug.Log(StringUtils.ToStringSansNamespace(subjectType) + " IUseDrawer override: " + StringUtils.ToStringSansNamespace(drawerType));
                                        #endif

                    drawersFor.fields[subjectType] = drawerType;
                }
                                #if DEV_MODE
                else
                {
                    Debug.LogError("IUseDrawer unrecognized drawerType: " + drawerType.Name + ". The drawer did not implement any of the necessary IDrawer-based interfaces.");
                }
                                #endif
            }

                        #if DEV_MODE && PI_ASSERTATIONS && UNITY_EDITOR
            Debug.Assert(!drawersFor.fields.ContainsValue(null));
            Debug.Assert(!drawersFor.fields.ContainsValue(typeof(PropertyDrawerDrawer)));
            Debug.Assert(!drawersFor.fields.ContainsValue(typeof(DecoratorDrawerDrawer)));

            Debug.Assert(!drawersFor.decoratorDrawers.ContainsValue(null));
            Debug.Assert(!drawersFor.decoratorDrawers.ContainsValue(typeof(PropertyDrawerDrawer)));
            foreach (var propertyDrawerDrawerBySecondType in drawersFor.propertyDrawersByAttributeType.Values)
            {
                Debug.Assert(!propertyDrawerDrawerBySecondType.ContainsValue(null));
                Debug.Assert(!propertyDrawerDrawerBySecondType.ContainsValue(typeof(DecoratorDrawerDrawer)));
            }
            Debug.Assert(!drawersFor.propertyDrawersByFieldType.ContainsValue(null));
            Debug.Assert(!drawersFor.propertyDrawersByFieldType.ContainsValue(typeof(DecoratorDrawerDrawer)));

            Debug.Assert(!drawersFor.components.ContainsValue(null));
            Debug.Assert(!drawersFor.components.ContainsValue(typeof(CustomEditorAssetDrawer)));
            Debug.Assert(!drawersFor.components.ContainsValue(typeof(AssetDrawer)));

            Debug.Assert(!drawersFor.assets.ContainsValue(null));
            Debug.Assert(!drawersFor.assets.ContainsValue(typeof(CustomEditorComponentDrawer)));
            Debug.Assert(!drawersFor.assets.ContainsValue(typeof(ComponentDrawer)));
            Debug.Assert(!drawersFor.assetsByExtension.ContainsValue(typeof(CustomEditorComponentDrawer)));
            Debug.Assert(!drawersFor.assetsByExtension.ContainsValue(typeof(ComponentDrawer)));
                        #endif
        }