protected virtual Type GetDrawerTypeForMethod([NotNull] MethodInfo methodInfo) { Type drawerType; if (UseDrawerAttributeUtility.TryGetCustomDrawerForClassMember(this, methodInfo, out drawerType)) { return(drawerType); } return(typeof(MethodDrawer)); }
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)); } }
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)); }
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 }