Beispiel #1
0
        protected override void Initialize()
        {
            var property  = this.Property;
            var attribute = this.Attribute;

            this.contextMenuInfos = property.Context.GetGlobal("CustomContextMenu", (Dictionary <CustomContextMenuAttribute, ContextMenuInfo>)null);
            this.populated        = property.Context.GetGlobal("CustomContextMenu_Populated", false);

            if (contextMenuInfos.Value == null)
            {
                contextMenuInfos.Value = new Dictionary <CustomContextMenuAttribute, ContextMenuInfo>();
            }

            if (!contextMenuInfos.Value.TryGetValue(attribute, out this.info))
            {
                this.info = new ContextMenuInfo();

                var methodInfo = property.ParentType
                                 .FindMember()
                                 .IsMethod()
                                 .IsInstance()
                                 .HasNoParameters()
                                 .ReturnsVoid()
                                 .IsNamed(attribute.MethodName)
                                 .GetMember <MethodInfo>(out this.info.ErrorMessage);

                if (this.info.ErrorMessage == null)
                {
                    this.info.Name         = attribute.MenuItem;
                    this.info.MethodCaller = EmitUtilities.CreateWeakInstanceMethodCaller(methodInfo);
                }

                contextMenuInfos.Value[attribute] = this.info;
            }
        }
        /// <summary>
        /// Draws the property.
        /// </summary>
        protected override void DrawPropertyLayout(InspectorProperty property, OnInspectorGUIAttribute attribute, GUIContent label)
        {
            if (property.Info.PropertyType == PropertyType.Method)
            {
                var methodConfig = property.Context.Get(this, "Config", (MethodContext)null);

                if (methodConfig.Value == null)
                {
                    methodConfig.Value = new MethodContext();

                    MethodInfo methodInfo = property.Info.MemberInfo as MethodInfo;

                    if (methodInfo.ReturnType != typeof(void))
                    {
                        methodConfig.Value.ErrorMessage = "The method '" + methodInfo.Name + "' must have a return type of type void.";
                    }
                    else if (methodInfo.GetParameters().Length > 0)
                    {
                        methodConfig.Value.ErrorMessage = "The method '" + methodInfo.Name + "' cannot take any parameters.";
                    }
                    else
                    {
                        methodConfig.Value.InstanceMethod = EmitUtilities.CreateWeakInstanceMethodCaller(methodInfo);
                    }
                }

                if (methodConfig.Value.ErrorMessage != null)
                {
                    SirenixEditorGUI.ErrorMessageBox(methodConfig.Value.ErrorMessage);
                }
                else
                {
                    if (methodConfig.Value.InstanceMethod != null)
                    {
                        methodConfig.Value.InstanceMethod(property.ParentValues[0]);
                    }
                }
            }
            else
            {
                if (attribute.PrependMethodName != null)
                {
                    this.DoInspectorGUI(property, "Prepend", attribute.PrependMethodName);
                }

                this.CallNextDrawer(property, label);

                if (attribute.AppendMethodName != null)
                {
                    this.DoInspectorGUI(property, "Append", attribute.AppendMethodName);
                }
            }
        }
Beispiel #3
0
    protected override void Initialize()
    {
        this.isListElement = this.Property.Parent != null && this.Property.Parent.ChildResolver is IOrderedCollectionResolver;
        var isList       = !this.isListElement;
        var listProperty = isList ? this.Property : this.Property.Parent;

        this.baseMemberProperty     = listProperty.FindParent(x => x.Info.PropertyType == PropertyType.Value, true);
        this.globalSelectedProperty = this.baseMemberProperty.Context.GetGlobal("selectedIndex" + this.baseMemberProperty.GetHashCode(), (InspectorProperty)null);

        if (isList)
        {
            var parentType = this.baseMemberProperty.ParentValues[0].GetType();
            this.selectedIndexSetter = EmitUtilities.CreateWeakInstanceMethodCaller <int>(parentType.GetMethod(this.Attribute.SetSelectedMethod, Flags.AllMembers));
        }
    }
        /// <summary>
        /// Draws the property.
        /// </summary>
        protected override void DrawPropertyLayout(GUIContent label)
        {
            var property  = this.Property;
            var attribute = this.Attribute;

            var contextMenuInfos = property.Context.GetGlobal("CustomContextMenu", (Dictionary <CustomContextMenuAttribute, ContextMenuInfo>)null);
            var populated        = property.Context.GetGlobal("CustomContextMenu_Populated", false);

            populated.Value = false;

            if (contextMenuInfos.Value == null)
            {
                contextMenuInfos.Value = new Dictionary <CustomContextMenuAttribute, ContextMenuInfo>();
            }

            ContextMenuInfo info;

            if (!contextMenuInfos.Value.TryGetValue(attribute, out info))
            {
                info = new ContextMenuInfo();

                var methodInfo = property.ParentType
                                 .FindMember()
                                 .IsMethod()
                                 .IsInstance()
                                 .HasNoParameters()
                                 .ReturnsVoid()
                                 .IsNamed(attribute.MethodName)
                                 .GetMember <MethodInfo>(out info.ErrorMessage);

                if (info.ErrorMessage == null)
                {
                    info.Name         = attribute.MenuItem;
                    info.MethodCaller = EmitUtilities.CreateWeakInstanceMethodCaller(methodInfo);
                }

                contextMenuInfos.Value[attribute] = info;
            }

            if (info.ErrorMessage != null)
            {
                SirenixEditorGUI.ErrorMessageBox(info.ErrorMessage);
            }

            this.CallNextDrawer(label);
        }
Beispiel #5
0
        private static void EnsureInitialized()
        {
            if (!Initialized)
            {
                Initialized = true;

                try
                {
                    string haveAudioCallbackName = UnityVersion.IsVersionOrGreater(5, 6) ? "HasAudioCallback" : "HaveAudioCallback";

                    AudioUtil_HaveAudioCallback           = (Func <MonoBehaviour, bool>)Delegate.CreateDelegate(typeof(Func <MonoBehaviour, bool>), typeof(Editor).Assembly.GetType("UnityEditor.AudioUtil").GetMethod(haveAudioCallbackName, BindingFlags.Public | BindingFlags.Static));
                    AudioUtil_GetCustomFilterChannelCount = (Func <MonoBehaviour, int>)Delegate.CreateDelegate(typeof(Func <MonoBehaviour, int>), typeof(Editor).Assembly.GetType("UnityEditor.AudioUtil").GetMethod("GetCustomFilterChannelCount", BindingFlags.Public | BindingFlags.Static));
                    AudioFilterGUIType      = typeof(Editor).Assembly.GetType("UnityEditor.AudioFilterGUI");
                    DrawAudioFilterGUI      = EmitUtilities.CreateWeakInstanceMethodCaller <MonoBehaviour>(AudioFilterGUIType.GetMethod("DrawAudioFilterGUI", BindingFlags.Public | BindingFlags.Instance));
                    HasReflectedAudioFilter = true;
                }
                catch (Exception)
                {
                    Debug.LogWarning("The internal Unity class AudioFilterGUI has been changed; cannot properly mock a generic Unity inspector. This probably won't be very noticeable.");
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Not yet documented.
        /// </summary>
        protected override void DrawPropertyLayout(GUIContent label)
        {
            var entry     = this.ValueEntry;
            var attribute = this.Attribute;

            var config = entry.Property.Context.Get(this, "Test", (CurrentContext)null);

            if (config.Value == null)
            {
                config.Value           = new CurrentContext();
                config.Value.Attribute = attribute;
                config.Value.Tags      = attribute.Tags != null?attribute.Tags.Trim().Split(',').Select(i => i.Trim()).ToArray() : null;

                config.Value.LayerNames = attribute.LayerNames != null?attribute.LayerNames.Trim().Split(',').Select(i => i.Trim()).ToArray() : null;

                config.Value.Property = entry.Property;
                if (attribute.Path != null)
                {
                    var path = attribute.Path.Trim('/', ' ');
                    path = "Assets/" + path + "/";
                    path = Application.dataPath + "/" + path;

                    config.Value.AssetsFolderLocation = new DirectoryInfo(path);

                    path = attribute.Path.TrimStart('/').TrimEnd('/');
                    config.Value.PrettyPath = "/" + path.TrimStart('/');
                }

                if (attribute.CustomFilterMethod != null)
                {
                    MethodInfo methodInfo;
                    string     error;
                    if (MemberFinder.Start(entry.ParentType)
                        .IsMethod()
                        .IsNamed(attribute.CustomFilterMethod)
                        .HasReturnType <bool>()
                        .HasParameters <TElement>()
                        .TryGetMember <MethodInfo>(out methodInfo, out error))
                    {
                        if (methodInfo.IsStatic)
                        {
                            config.Value.StaticCustomIncludeMethod = (Func <TElement, bool>)Delegate.CreateDelegate(typeof(Func <TElement, bool>), methodInfo, true);
                        }
                        else
                        {
                            config.Value.InstanceCustomIncludeMethod = EmitUtilities.CreateWeakInstanceMethodCaller <bool, TElement>(methodInfo);
                        }
                    }

                    config.Value.ErrorMessage = error;
                }

                if (config.Value.ErrorMessage != null)
                {
                    // We can get away with lag on load.
                    config.Value.MaxSearchDurationPrFrameInMS = 20;
                    config.Value.EnsureListPopulation();
                    config.Value.MaxSearchDurationPrFrameInMS = 1;
                }
            }

            var currentValue = (UnityEngine.Object)entry.WeakSmartValue;

            if (config.Value.ErrorMessage != null)
            {
                SirenixEditorGUI.ErrorMessageBox(config.Value.ErrorMessage);
            }
            else
            {
                config.Value.EnsureListPopulation();
            }

            SirenixEditorGUI.BeginIndentedVertical(SirenixGUIStyles.PropertyPadding);
            {
                SirenixEditorGUI.BeginHorizontalToolbar();
                if (label != null)
                {
                    GUILayout.Label(label);
                }

                GUILayout.FlexibleSpace();
                if (config.Value.PrettyPath != null)
                {
                    GUILayout.Label(config.Value.PrettyPath, SirenixGUIStyles.RightAlignedGreyMiniLabel);
                    SirenixEditorGUI.VerticalLineSeparator();
                }

                if (config.Value.IsPopulated)
                {
                    GUILayout.Label(config.Value.AvailableAsset.Count + " items", SirenixGUIStyles.RightAlignedGreyMiniLabel);
                    GUIHelper.PushGUIEnabled(GUI.enabled && (config.Value.AvailableAsset.Count > 0 && config.Value.ErrorMessage == null));
                }
                else
                {
                    GUILayout.Label("Scanning " + config.Value.CurrentSearchingIndex + " / " + config.Value.NumberOfResultsToSearch, SirenixGUIStyles.RightAlignedGreyMiniLabel);
                    GUIHelper.PushGUIEnabled(false);
                }

                SirenixEditorGUI.VerticalLineSeparator();

                bool drawConflict = entry.Property.ParentValues.Count > 1;
                if (drawConflict == false)
                {
                    var index = config.Value.AvailableAsset.IndexOf(currentValue) + 1;
                    if (index > 0)
                    {
                        GUILayout.Label(index.ToString(), SirenixGUIStyles.RightAlignedGreyMiniLabel);
                    }
                    else
                    {
                        drawConflict = true;
                    }
                }

                if (drawConflict)
                {
                    GUILayout.Label("-", SirenixGUIStyles.RightAlignedGreyMiniLabel);
                }

                if (SirenixEditorGUI.ToolbarButton(EditorIcons.TriangleLeft) && config.Value.IsPopulated)
                {
                    var index = config.Value.AvailableAsset.IndexOf(currentValue) - 1;
                    index = index < 0 ? config.Value.AvailableAsset.Count - 1 : index;
                    entry.WeakSmartValue = config.Value.AvailableAsset[index];
                }

                if (SirenixEditorGUI.ToolbarButton(EditorIcons.TriangleDown) && config.Value.IsPopulated)
                {
                    GenericMenu m            = new GenericMenu();
                    var         selected     = currentValue;
                    int         itemsPrPage  = 40;
                    bool        showPages    = config.Value.AvailableAsset.Count > 50;
                    string      page         = "";
                    int         selectedPage = (config.Value.AvailableAsset.IndexOf(entry.WeakSmartValue as UnityEngine.Object) / itemsPrPage);
                    for (int i = 0; i < config.Value.AvailableAsset.Count; i++)
                    {
                        var obj = config.Value.AvailableAsset[i];
                        if (obj != null)
                        {
                            var path       = AssetDatabase.GetAssetPath(obj);
                            var name       = string.IsNullOrEmpty(path) ? obj.name : path.Substring(7).Replace("/", "\\");
                            var localEntry = entry;

                            if (showPages)
                            {
                                var p = (i / itemsPrPage);
                                page = (p * itemsPrPage) + " - " + Mathf.Min(((p + 1) * itemsPrPage), config.Value.AvailableAsset.Count - 1);
                                if (selectedPage == p)
                                {
                                    page += " (contains selected)";
                                }
                                page += "/";
                            }

                            m.AddItem(new GUIContent(page + name), obj == selected, () =>
                            {
                                localEntry.Property.Tree.DelayActionUntilRepaint(() => localEntry.WeakSmartValue = obj);
                            });
                        }
                    }
                    m.ShowAsContext();
                }

                if (SirenixEditorGUI.ToolbarButton(EditorIcons.TriangleRight) && config.Value.IsPopulated)
                {
                    var index = config.Value.AvailableAsset.IndexOf(currentValue) + 1;
                    entry.WeakSmartValue = config.Value.AvailableAsset[index % config.Value.AvailableAsset.Count];
                }

                GUIHelper.PopGUIEnabled();

                SirenixEditorGUI.EndHorizontalToolbar();
                SirenixEditorGUI.BeginVerticalList();
                SirenixEditorGUI.BeginListItem(false, padding);
                this.CallNextDrawer(null);
                SirenixEditorGUI.EndListItem();
                SirenixEditorGUI.EndVerticalList();
            }
            SirenixEditorGUI.EndIndentedVertical();
        }
        private void DoInspectorGUI(InspectorProperty property, string config, string methodName)
        {
            var methodConfig = property.Context.Get(this, config, (MethodContext)null);

            if (methodConfig.Value == null)
            {
                methodConfig.Value = new MethodContext();

                MethodInfo methodInfo = property.ParentType
                                        .FindMember()
                                        .IsMethod()
                                        .IsNamed(methodName)
                                        .HasNoParameters()
                                        .ReturnsVoid()
                                        .GetMember <MethodInfo>(out methodConfig.Value.ErrorMessage);

                if (methodConfig.Value.ErrorMessage == null && methodInfo != null)
                {
                    if (methodInfo.IsStatic)
                    {
                        methodConfig.Value.StaticMethod = EmitUtilities.CreateStaticMethodCaller(methodInfo);
                    }
                    else
                    {
                        methodConfig.Value.InstanceMethod = EmitUtilities.CreateWeakInstanceMethodCaller(methodInfo);
                    }
                }
                else
                {
                    string otherErrorMessage;
                    methodInfo = property.ParentType
                                 .FindMember()
                                 .IsMethod()
                                 .IsNamed(methodName)
                                 .HasParameters(property.ValueEntry.BaseValueType)
                                 .IsStatic()
                                 .ReturnsVoid()
                                 .GetMember <MethodInfo>(out otherErrorMessage);

                    if (otherErrorMessage == null)
                    {
                        methodConfig.Value.ErrorMessage = null;
                        var delegateType = typeof(Action <>).MakeGenericType(property.ValueEntry.TypeOfValue);
                        methodConfig.Value.StaticMethodWithParam = Delegate.CreateDelegate(delegateType, methodInfo);
                    }
                    else
                    {
                        methodConfig.Value.ErrorMessage += "\nor\n" + otherErrorMessage;
                    }
                }
            }

            if (methodConfig.Value.ErrorMessage != null)
            {
                SirenixEditorGUI.ErrorMessageBox(methodConfig.Value.ErrorMessage);
            }
            else
            {
                if (methodConfig.Value.InstanceMethod != null)
                {
                    methodConfig.Value.InstanceMethod(property.ParentValues[0]);
                }
                else if (methodConfig.Value.StaticMethodWithParam != null)
                {
                    methodConfig.Value.StaticMethodWithParam.DynamicInvoke(property.ValueEntry.WeakSmartValue);
                }
                else
                {
                    methodConfig.Value.StaticMethod();
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// Initializes the drawer.
        /// </summary>
        protected override void Initialize()
        {
            var  resolver   = this.Property.ChildResolver as ICollectionResolver;
            bool isReadOnly = resolver.IsReadOnly;

            var customListDrawerOptions = this.Property.GetAttribute <ListDrawerSettingsAttribute>() ?? new ListDrawerSettingsAttribute();

            isReadOnly = this.ValueEntry.IsEditable == false || isReadOnly || customListDrawerOptions.IsReadOnlyHasValue && customListDrawerOptions.IsReadOnly;

            info = new ListDrawerConfigInfo()
            {
                StartIndex = 0,
                Toggled    = this.ValueEntry.Context.GetPersistent <bool>(this, "ListDrawerToggled", customListDrawerOptions.ExpandedHasValue ? customListDrawerOptions.Expanded : GeneralDrawerConfig.Instance.OpenListsByDefault),
                RemoveAt   = -1,

                // Now set further down, so it can be kept updated every frame
                //Label = new GUIContent(label == null || string.IsNullOrEmpty(label.text) ? this.Property.ValueEntry.TypeOfValue.GetNiceName() : label.text, label == null ? string.Empty : label.tooltip),
                ShowAllWhilePaging      = false,
                EndIndex                = 0,
                CustomListDrawerOptions = customListDrawerOptions,
                IsReadOnly              = isReadOnly,
                Draggable               = !isReadOnly && (!customListDrawerOptions.IsReadOnlyHasValue),
                HideAddButton           = isReadOnly || customListDrawerOptions.HideAddButton,
                HideRemoveButton        = isReadOnly || customListDrawerOptions.HideRemoveButton,
            };

            info.ListConfig = GeneralDrawerConfig.Instance;
            info.Property   = this.Property;

            if (customListDrawerOptions.DraggableHasValue && !customListDrawerOptions.DraggableItems)
            {
                info.Draggable = false;
            }

            if (!(this.Property.ChildResolver is IOrderedCollectionResolver))
            {
                info.Draggable = false;
            }

            if (info.CustomListDrawerOptions.OnBeginListElementGUI != null)
            {
                string     error;
                MemberInfo memberInfo = this.Property.ParentType
                                        .FindMember()
                                        .IsMethod()
                                        .IsNamed(info.CustomListDrawerOptions.OnBeginListElementGUI)
                                        .HasParameters <int>()
                                        .ReturnsVoid()
                                        .GetMember <MethodInfo>(out error);

                if (memberInfo == null || error != null)
                {
                    // TOOD: Do something about this "There should really be an error message here." thing.
                    // For this to trigger both the member and the error message should be null. Can that happen?
                    this.errorMessage = error ?? "There should really be an error message here.";
                }
                else
                {
                    info.OnBeginListElementGUI = EmitUtilities.CreateWeakInstanceMethodCaller <int>(memberInfo as MethodInfo);
                }
            }

            if (info.CustomListDrawerOptions.OnEndListElementGUI != null)
            {
                string     error;
                MemberInfo memberInfo = this.Property.ParentType
                                        .FindMember()
                                        .IsMethod()
                                        .IsNamed(info.CustomListDrawerOptions.OnEndListElementGUI)
                                        .HasParameters <int>()
                                        .ReturnsVoid()
                                        .GetMember <MethodInfo>(out error);

                if (memberInfo == null || error != null)
                {
                    // TOOD: Do something about this "There should really be an error message here." thing.
                    // For this to trigger both the member and the error message should be null. Can that happen?
                    this.errorMessage = error ?? "There should really be an error message here.";
                }
                else
                {
                    info.OnEndListElementGUI = EmitUtilities.CreateWeakInstanceMethodCaller <int>(memberInfo as MethodInfo);
                }
            }

            if (info.CustomListDrawerOptions.OnTitleBarGUI != null)
            {
                string     error;
                MemberInfo memberInfo = this.Property.ParentType
                                        .FindMember()
                                        .IsMethod()
                                        .IsNamed(info.CustomListDrawerOptions.OnTitleBarGUI)
                                        .HasNoParameters()
                                        .ReturnsVoid()
                                        .GetMember <MethodInfo>(out error);

                if (memberInfo == null || error != null)
                {
                    // TOOD: Do something about this "There should really be an error message here." thing.
                    // For this to trigger both the member and the error message should be null. Can that happen?
                    this.errorMessage = error ?? "There should really be an error message here.";
                }
                else
                {
                    info.OnTitleBarGUI = EmitUtilities.CreateWeakInstanceMethodCaller(memberInfo as MethodInfo);
                }
            }

            if (info.CustomListDrawerOptions.ListElementLabelName != null)
            {
                string     error;
                MemberInfo memberInfo = resolver.ElementType
                                        .FindMember()
                                        .HasNoParameters()
                                        .IsNamed(info.CustomListDrawerOptions.ListElementLabelName)
                                        .HasReturnType <object>(true)
                                        .GetMember(out error);

                if (memberInfo == null || error != null)
                {
                    // TOOD: Do something about this "There should really be an error message here." thing.
                    // For this to trigger both the member and the error message should be null. Can that happen?
                    this.errorMessage = error ?? "There should really be an error message here.";
                }
                else
                {
                    string methodSuffix = memberInfo as MethodInfo == null ? "" : "()";
                    info.GetListElementLabelText = DeepReflection.CreateWeakInstanceValueGetter(resolver.ElementType, typeof(object), info.CustomListDrawerOptions.ListElementLabelName + methodSuffix);
                }
            }

            // Resolve custom add method member reference.
            if (info.CustomListDrawerOptions.CustomAddFunction != null)
            {
                string     error;
                MemberInfo memberInfo = this.Property.ParentType
                                        .FindMember()
                                        .HasNoParameters()
                                        .IsNamed(info.CustomListDrawerOptions.CustomAddFunction)
                                        .IsInstance()
                                        .HasReturnType(resolver.ElementType)
                                        .GetMember(out error);

                if (memberInfo == null || error != null)
                {
                    string error2;

                    memberInfo = this.Property.ParentType
                                 .FindMember()
                                 .IsMethod()
                                 .HasNoParameters()
                                 .IsNamed(info.CustomListDrawerOptions.CustomAddFunction)
                                 .IsInstance()
                                 .ReturnsVoid()
                                 .GetMember(out error2);

                    if (memberInfo == null || error2 != null)
                    {
                        this.errorMessage = error + " - or - " + error2;
                    }
                    else
                    {
                        info.GetCustomAddFunctionVoid = EmitUtilities.CreateWeakInstanceMethodCaller(memberInfo as MethodInfo);
                    }
                }
                else
                {
                    string methodSuffix = memberInfo as MethodInfo == null ? "" : "()";
                    info.GetCustomAddFunction = DeepReflection.CreateWeakInstanceValueGetter(
                        this.Property.ParentType,
                        resolver.ElementType,
                        info.CustomListDrawerOptions.CustomAddFunction + methodSuffix
                        );
                }
            }

            // Resolve custom remove index method member reference.
            if (info.CustomListDrawerOptions.CustomRemoveIndexFunction != null)
            {
                if (this.Property.ChildResolver is IOrderedCollectionResolver == false)
                {
                    this.errorMessage = "ListDrawerSettings.CustomRemoveIndexFunction is invalid on unordered collections. Use ListDrawerSetings.CustomRemoveElementFunction instead.";
                }
                else
                {
                    MethodInfo method = this.Property.ParentType
                                        .FindMember()
                                        .IsNamed(info.CustomListDrawerOptions.CustomRemoveIndexFunction)
                                        .IsMethod()
                                        .IsInstance()
                                        .HasParameters <int>()
                                        .ReturnsVoid()
                                        .GetMember <MethodInfo>(out this.errorMessage);

                    if (method != null)
                    {
                        info.CustomRemoveIndexFunction = EmitUtilities.CreateWeakInstanceMethodCaller <int>(method);
                    }
                }
            }
            // Resolve custom remove element method member reference.
            else if (info.CustomListDrawerOptions.CustomRemoveElementFunction != null)
            {
                var element = (this.Property.ChildResolver as ICollectionResolver).ElementType;

                MethodInfo method = this.Property.ParentType
                                    .FindMember()
                                    .IsNamed(info.CustomListDrawerOptions.CustomRemoveElementFunction)
                                    .IsMethod()
                                    .IsInstance()
                                    .HasParameters(element)
                                    .ReturnsVoid()
                                    .GetMember <MethodInfo>(out this.errorMessage);

                if (method != null)
                {
                    // TOOD: Emit dis.
                    info.CustomRemoveElementFunction = (o, e) => method.Invoke(o, new object[] { e });
                }
            }
        }
        /// <summary>
        /// Draws the property.
        /// </summary>
        protected override void DrawPropertyLayout(GUIContent label)
        {
            var property  = this.Property;
            var entry     = this.ValueEntry;
            var attribute = this.Attribute;

            var assetList    = property.Context.Get(this, "assetList", (AssetList)null);
            var propertyTree = property.Context.Get(this, "togglableAssetListPropertyTree", (PropertyTree)null);

            if (property.ValueEntry.WeakSmartValue == null)
            {
                return;
            }

            if (assetList.Value == null)
            {
                assetList.Value = new AssetList();
                assetList.Value.AutoPopulate    = attribute.AutoPopulate;
                assetList.Value.AssetNamePrefix = attribute.AssetNamePrefix;
                assetList.Value.Tags            = attribute.Tags != null?attribute.Tags.Trim().Split(',').Select(i => i.Trim()).ToArray() : null;

                assetList.Value.LayerNames = attribute.LayerNames != null?attribute.LayerNames.Trim().Split(',').Select(i => i.Trim()).ToArray() : null;

                assetList.Value.List = entry;
                assetList.Value.CollectionResolver = property.ChildResolver as IOrderedCollectionResolver;
                assetList.Value.Property           = entry.Property;

                if (attribute.Path != null)
                {
                    var path = attribute.Path.TrimStart('/', ' ').TrimEnd('/', ' ');
                    path = attribute.Path.Trim('/', ' ');

                    path = "Assets/" + path + "/";
                    path = Application.dataPath + "/" + path;

                    assetList.Value.AssetsFolderLocation = new DirectoryInfo(path);

                    path = attribute.Path.Trim('/', ' ');
                    assetList.Value.PrettyPath = "/" + path.TrimStart('/');
                }

                if (attribute.CustomFilterMethod != null)
                {
                    MethodInfo methodInfo;
                    string     error;
                    if (MemberFinder.Start(entry.ParentType)
                        .IsMethod()
                        .IsNamed(attribute.CustomFilterMethod)
                        .HasReturnType <bool>()
                        .HasParameters <TElement>()
                        .TryGetMember <MethodInfo>(out methodInfo, out error))
                    {
                        if (methodInfo.IsStatic)
                        {
                            assetList.Value.StaticCustomIncludeMethod = (Func <TElement, bool>)Delegate.CreateDelegate(typeof(Func <TElement, bool>), methodInfo, true);
                        }
                        else
                        {
                            assetList.Value.InstanceCustomIncludeMethod = EmitUtilities.CreateWeakInstanceMethodCaller <bool, TElement>(methodInfo);
                        }
                    }

                    assetList.Value.ErrorMessage = error;
                }

                // We can get away with lag on load.
                assetList.Value.MaxSearchDurationPrFrameInMS = 20;
                assetList.Value.EnsureListPopulation();
                assetList.Value.MaxSearchDurationPrFrameInMS = 1;

                //assetList.Value.List = list;

                //if (propertyTree.Value == null)
                //{
                propertyTree.Value = PropertyTree.Create(assetList.Value);
                propertyTree.Value.UpdateTree();
                propertyTree.Value.GetRootProperty(0).Label = label;
                //}
            }
            else if (Event.current.type == EventType.Layout)
            {
                assetList.Value.Property = entry.Property;
                assetList.Value.EnsureListPopulation();
                assetList.Value.SetToggleValues();
            }

            if (assetList.Value.ErrorMessage != null)
            {
                SirenixEditorGUI.ErrorMessageBox(assetList.Value.ErrorMessage);
            }
            assetList.Value.Property = entry.Property;
            propertyTree.Value.Draw(false);

            if (Event.current.type == EventType.Used)
            {
                assetList.Value.UpdateList();
            }
        }
Beispiel #10
0
        /// <summary>
        /// Draws the property.
        /// </summary>
        protected override void DrawPropertyLayout(IPropertyValueEntry <T> entry, DetailedInfoBoxAttribute attribute, GUIContent label)
        {
            PropertyContext <InfoBoxContext> context = entry.Property.Context.Get(this, "Context", (InfoBoxContext)null);

            if (context.Value == null)
            {
                context.Value = new InfoBoxContext()
                {
                    MessageHelper = new StringMemberHelper(entry.ParentType, attribute.Message),
                    DetailsHelper = new StringMemberHelper(entry.ParentType, attribute.Details)
                };

                context.Value.ErrorMessage = context.Value.MessageHelper.ErrorMessage ?? context.Value.DetailsHelper.ErrorMessage;

                if (attribute.VisibleIf != null)
                {
                    MemberInfo memberInfo;

                    // Parameter functions
                    if (entry.ParentType.FindMember()
                        .IsMethod()
                        .HasReturnType <bool>()
                        .HasParameters <T>()
                        .IsNamed(attribute.VisibleIf)
                        .TryGetMember(out memberInfo, out context.Value.ErrorMessage))
                    {
                        if (context.Value.ErrorMessage == null)
                        {
                            if (memberInfo is MethodInfo)
                            {
                                if (memberInfo.IsStatic())
                                {
                                    context.Value.StaticValidationParameterMethodCaller = (Func <T, bool>)Delegate.CreateDelegate(typeof(Func <T, bool>), memberInfo as MethodInfo);
                                }
                                else
                                {
                                    context.Value.InstanceValidationParameterMethodCaller = EmitUtilities.CreateWeakInstanceMethodCaller <bool, T>(memberInfo as MethodInfo);
                                }
                            }
                            else
                            {
                                context.Value.ErrorMessage = "Invalid member type!";
                            }
                        }
                    }
                    // Fields, properties, and no-parameter functions.
                    else if (entry.ParentType.FindMember()
                             .HasReturnType <bool>()
                             .HasNoParameters()
                             .IsNamed(attribute.VisibleIf)
                             .TryGetMember(out memberInfo, out context.Value.ErrorMessage))
                    {
                        if (context.Value.ErrorMessage == null)
                        {
                            if (memberInfo is FieldInfo)
                            {
                                if (memberInfo.IsStatic())
                                {
                                    context.Value.StaticValidationCaller = EmitUtilities.CreateStaticFieldGetter <bool>(memberInfo as FieldInfo);
                                }
                                else
                                {
                                    context.Value.InstanceValueGetter = EmitUtilities.CreateWeakInstanceFieldGetter(entry.ParentType, memberInfo as FieldInfo);
                                }
                            }
                            else if (memberInfo is PropertyInfo)
                            {
                                if (memberInfo.IsStatic())
                                {
                                    context.Value.StaticValidationCaller = EmitUtilities.CreateStaticPropertyGetter <bool>(memberInfo as PropertyInfo);
                                }
                                else
                                {
                                    context.Value.InstanceValueGetter = EmitUtilities.CreateWeakInstancePropertyGetter(entry.ParentType, memberInfo as PropertyInfo);
                                }
                            }
                            else if (memberInfo is MethodInfo)
                            {
                                if (memberInfo.IsStatic())
                                {
                                    context.Value.StaticValidationCaller = (Func <bool>)Delegate.CreateDelegate(typeof(Func <bool>), memberInfo as MethodInfo);
                                }
                                else
                                {
                                    context.Value.InstanceValidationMethodCaller = EmitUtilities.CreateWeakInstanceMethodCallerFunc <bool>(memberInfo as MethodInfo);
                                }
                            }
                            else
                            {
                                context.Value.ErrorMessage = "Invalid member type!";
                            }
                        }
                    }
                }
            }

            if (context.Value.ErrorMessage != null)
            {
                AllEditorGUI.ErrorMessageBox(context.Value.ErrorMessage);
            }
            else
            {
                if (Event.current.type == EventType.Layout)
                {
                    var parentValue = entry.Property.ParentValues[0];

                    try
                    {
                        if (entry.Property.ValueEntry != null)
                        {
                            context.Value.DrawMessageBox =
                                attribute.VisibleIf == null ||
                                (context.Value.StaticValidationParameterMethodCaller != null && context.Value.StaticValidationParameterMethodCaller(entry.SmartValue)) ||
                                (context.Value.InstanceValidationParameterMethodCaller != null && context.Value.InstanceValidationParameterMethodCaller(entry.Property.ParentValues[0], entry.SmartValue)) ||
                                (context.Value.InstanceValidationMethodCaller != null && context.Value.InstanceValidationMethodCaller(entry.Property.ParentValues[0])) ||
                                (context.Value.InstanceValueGetter != null && (bool)context.Value.InstanceValueGetter(ref parentValue)) ||
                                (context.Value.StaticValidationCaller != null && context.Value.StaticValidationCaller());
                        }
                    }
                    catch (System.Exception ex)
                    {
                        Debug.LogException(ex);
                    }
                }

                if (context.Value.DrawMessageBox)
                {
                    var foldedConfig = entry.Property.Context.GetPersistent <bool>(this, "InfoBoxExpanded", true);

                    switch (attribute.InfoMessageType)
                    {
                    case InfoMessageType.None:
                        foldedConfig.Value = AllEditorGUI.DetailedMessageBox(context.Value.MessageHelper.GetString(entry), context.Value.DetailsHelper.GetString(entry), UnityEditor.MessageType.None, foldedConfig.Value);
                        break;

                    case InfoMessageType.Info:
                        foldedConfig.Value = AllEditorGUI.DetailedMessageBox(context.Value.MessageHelper.GetString(entry), context.Value.DetailsHelper.GetString(entry), UnityEditor.MessageType.Info, foldedConfig.Value);
                        break;

                    case InfoMessageType.Warning:
                        foldedConfig.Value = AllEditorGUI.DetailedMessageBox(context.Value.MessageHelper.GetString(entry), context.Value.DetailsHelper.GetString(entry), UnityEditor.MessageType.Warning, foldedConfig.Value);
                        break;

                    case InfoMessageType.Error:
                        foldedConfig.Value = AllEditorGUI.DetailedMessageBox(context.Value.MessageHelper.GetString(entry), context.Value.DetailsHelper.GetString(entry), UnityEditor.MessageType.Error, foldedConfig.Value);
                        break;

                    default:
                        AllEditorGUI.ErrorMessageBox("Unknown InfoBoxType: " + attribute.InfoMessageType.ToString());
                        break;
                    }
                }
            }

            this.CallNextDrawer(entry.Property, label);
        }
        /// <summary>
        /// Draws the property.
        /// </summary>
        protected override void DrawPropertyLayout(IPropertyValueEntry <TList> entry, GUIContent label)
        {
            var property    = entry.Property;
            var infoContext = property.Context.Get(this, "Context", (ListDrawerConfigInfo)null);
            var info        = infoContext.Value;

            bool isReadOnly = false;

            if (entry.TypeOfValue.IsArray == false)
            {
                for (int i = 0; i < entry.ValueCount; i++)
                {
                    if ((entry.WeakValues[i] as IList <TElement>).IsReadOnly)
                    {
                        isReadOnly = true;
                        break;
                    }
                }
            }

            if (info == null)
            {
                var customListDrawerOptions = property.Info.GetAttribute <ListDrawerSettingsAttribute>() ?? new ListDrawerSettingsAttribute();
                isReadOnly = entry.IsEditable == false || isReadOnly || customListDrawerOptions.IsReadOnlyHasValue && customListDrawerOptions.IsReadOnly;

                info = infoContext.Value = new ListDrawerConfigInfo()
                {
                    StartIndex              = 0,
                    Toggled                 = entry.Context.GetPersistent <bool>(this, "ListDrawerToggled", customListDrawerOptions.ExpandedHasValue ? customListDrawerOptions.Expanded : GeneralDrawerConfig.Instance.OpenListsByDefault),
                    RemoveAt                = -1,
                    label                   = new GUIContent(label == null || string.IsNullOrEmpty(label.text) ? property.ValueEntry.TypeOfValue.GetNiceName() : label.text, label == null ? string.Empty : label.tooltip),
                    ShowAllWhilePageing     = false,
                    EndIndex                = 0,
                    CustomListDrawerOptions = customListDrawerOptions,
                    IsReadOnly              = isReadOnly,
                    Draggable               = !isReadOnly && (!customListDrawerOptions.IsReadOnlyHasValue)
                };

                info.listConfig = GeneralDrawerConfig.Instance;
                info.property   = property;

                if (customListDrawerOptions.DraggableHasValue && !customListDrawerOptions.DraggableItems)
                {
                    info.Draggable = false;
                }

                if (info.CustomListDrawerOptions.OnBeginListElementGUI != null)
                {
                    string     errorMessage;
                    MemberInfo memberInfo = property.ParentType
                                            .FindMember()
                                            .IsMethod()
                                            .IsNamed(info.CustomListDrawerOptions.OnBeginListElementGUI)
                                            .HasParameters <int>()
                                            .ReturnsVoid()
                                            .GetMember <MethodInfo>(out errorMessage);

                    if (memberInfo == null || errorMessage != null)
                    {
                        Debug.LogError(errorMessage ?? "There should really be an error message here.");
                    }
                    else
                    {
                        info.OnBeginListElementGUI = EmitUtilities.CreateWeakInstanceMethodCaller <int>(memberInfo as MethodInfo);
                    }
                }

                if (info.CustomListDrawerOptions.OnEndListElementGUI != null)
                {
                    string     errorMessage;
                    MemberInfo memberInfo = property.ParentType
                                            .FindMember()
                                            .IsMethod()
                                            .IsNamed(info.CustomListDrawerOptions.OnEndListElementGUI)
                                            .HasParameters <int>()
                                            .ReturnsVoid()
                                            .GetMember <MethodInfo>(out errorMessage);

                    if (memberInfo == null || errorMessage != null)
                    {
                        Debug.LogError(errorMessage ?? "There should really be an error message here.");
                    }
                    else
                    {
                        info.OnEndListElementGUI = EmitUtilities.CreateWeakInstanceMethodCaller <int>(memberInfo as MethodInfo);
                    }
                }

                if (info.CustomListDrawerOptions.OnTitleBarGUI != null)
                {
                    string     errorMessage;
                    MemberInfo memberInfo = property.ParentType
                                            .FindMember()
                                            .IsMethod()
                                            .IsNamed(info.CustomListDrawerOptions.OnTitleBarGUI)
                                            .HasNoParameters()
                                            .ReturnsVoid()
                                            .GetMember <MethodInfo>(out errorMessage);

                    if (memberInfo == null || errorMessage != null)
                    {
                        Debug.LogError(errorMessage ?? "There should really be an error message here.");
                    }
                    else
                    {
                        info.OnTitleBarGUI = EmitUtilities.CreateWeakInstanceMethodCaller(memberInfo as MethodInfo);
                    }
                }

                if (info.CustomListDrawerOptions.ListElementLabelName != null)
                {
                    string     errorMessage;
                    MemberInfo memberInfo = typeof(TElement)
                                            .FindMember()
                                            .HasNoParameters()
                                            .IsNamed(info.CustomListDrawerOptions.ListElementLabelName)
                                            .HasReturnType <object>(true)
                                            .GetMember(out errorMessage);

                    if (memberInfo == null || errorMessage != null)
                    {
                        Debug.LogError(errorMessage ?? "There should really be an error message here.");
                    }
                    else
                    {
                        string methodSuffix = memberInfo as MethodInfo == null ? "" : "()";
                        info.GetListElementLabelText = DeepReflection.CreateWeakInstanceValueGetter(typeof(TElement), typeof(object), info.CustomListDrawerOptions.ListElementLabelName + methodSuffix);
                    }
                }
            }

            info.listConfig = GeneralDrawerConfig.Instance;
            info.property   = property;

            info.ListItemStyle.padding.left  = info.Draggable ? 25 : 7;
            info.ListItemStyle.padding.right = info.IsReadOnly ? 4 : 20;

            if (Event.current.type == EventType.Repaint)
            {
                info.DropZoneTopLeft = GUIUtility.GUIToScreenPoint(new Vector2(0, 0));
            }

            info.ListValueChanger = property.ValueEntry.GetListValueEntryChanger();
            info.Count            = property.Children.Count;
            info.IsEmpty          = property.Children.Count == 0;

            SirenixEditorGUI.BeginIndentedVertical(SirenixGUIStyles.PropertyPadding);
            this.BeginDropZone(info);
            {
                this.DrawToolbar(info);
                if (SirenixEditorGUI.BeginFadeGroup(UniqueDrawerKey.Create(property, this), info.Toggled.Value))
                {
                    GUIHelper.PushLabelWidth(EditorGUIUtility.labelWidth - info.ListItemStyle.padding.left);
                    this.DrawItems(info);
                    GUIHelper.PopLabelWidth();
                }
                SirenixEditorGUI.EndFadeGroup();
            }
            this.EndDropZone(info);
            SirenixEditorGUI.EndIndentedVertical();

            if (info.RemoveAt >= 0 && Event.current.type == EventType.Repaint)
            {
                info.ListValueChanger.RemoveListElementAt(info.RemoveAt, CHANGE_ID);

                info.RemoveAt = -1;
                GUIHelper.RequestRepaint();
            }

            if (info.ObjectPicker != null && info.ObjectPicker.IsReadyToClaim && Event.current.type == EventType.Repaint)
            {
                var value = info.ObjectPicker.ClaimObject();

                if (info.JumpToNextPageOnAdd)
                {
                    info.StartIndex = int.MaxValue;
                }

                object[] values = new object[info.ListValueChanger.ValueCount];

                values[0] = value;
                for (int j = 1; j < values.Length; j++)
                {
                    values[j] = SerializationUtility.CreateCopy(value);
                }

                info.ListValueChanger.AddListElement(values, CHANGE_ID);
            }
        }
        /// <summary>
        /// Draws the property.
        /// </summary>
        protected override void DrawPropertyLayout(GUIContent label)
        {
            var entry     = this.ValueEntry;
            var attribute = this.Attribute;

            var context = entry.Property.Context.Get <ButtonContext>(this, "ButtonContext", (ButtonContext)null);

            if (context.Value == null)
            {
                context.Value             = new ButtonContext();
                context.Value.LabelHelper = new StringMemberHelper(this.Property, attribute.Label ?? attribute.MemberMethod.SplitPascalCase(), ref context.Value.ErrorMessage);

                if (context.Value.ErrorMessage == null)
                {
                    MethodInfo method;

                    if (MemberFinder.Start(entry.ParentType)
                        .IsMethod()
                        .IsNamed(attribute.MemberMethod)
                        .HasNoParameters()
                        .TryGetMember <MethodInfo>(out method, out context.Value.ErrorMessage))
                    {
                        if (method.IsStatic())
                        {
                            context.Value.StaticMethodCaller = EmitUtilities.CreateStaticMethodCaller(method);
                        }
                        else
                        {
                            context.Value.InstanceMethodCaller = EmitUtilities.CreateWeakInstanceMethodCaller(method);
                        }
                    }
                    else if (MemberFinder.Start(entry.ParentType)
                             .IsMethod()
                             .IsNamed(attribute.MemberMethod)
                             .HasParameters <T>()
                             .TryGetMember <MethodInfo>(out method, out context.Value.ErrorMessage))
                    {
                        if (method.IsStatic())
                        {
                            context.Value.ErrorMessage = "Static parameterized method is currently not supported.";
                        }
                        else
                        {
                            context.Value.InstanceParameterMethodCaller = EmitUtilities.CreateWeakInstanceMethodCaller <T>(method);
                        }
                    }
                }
            }

            if (context.Value.ErrorMessage != null)
            {
                SirenixEditorGUI.ErrorMessageBox(context.Value.ErrorMessage);
                this.CallNextDrawer(label);
            }
            else
            {
                EditorGUILayout.BeginHorizontal();

                EditorGUILayout.BeginVertical();
                this.CallNextDrawer(label);
                EditorGUILayout.EndVertical();

                if (GUILayout.Button(context.Value.LabelHelper.GetString(entry), EditorStyles.miniButton, GUILayoutOptions.ExpandWidth(false).MinWidth(20)))
                {
                    // Invoke method.
                    if (context.Value.StaticMethodCaller != null)
                    {
                        context.Value.StaticMethodCaller();
                    }
                    //else if(context.Value.StaticParameterMethodCaller != null)
                    //{
                    //	context.Value.StaticParameterMethodCaller(entry.SmartValue);
                    //}
                    else if (context.Value.InstanceMethodCaller != null)
                    {
                        context.Value.InstanceMethodCaller(entry.Property.ParentValues[0]);
                    }
                    else if (context.Value.InstanceParameterMethodCaller != null)
                    {
                        context.Value.InstanceParameterMethodCaller(entry.Property.ParentValues[0], entry.SmartValue);
                    }
                    else
                    {
                        Debug.LogError("No method found.");
                    }
                }

                EditorGUILayout.EndHorizontal();
            }
        }
Beispiel #13
0
        /// <summary>
        /// Draws the property.
        /// </summary>
        protected override void DrawPropertyImplementation(InspectorProperty property, GUIContent label)
        {
            if (buttonStyle == null)
            {
                buttonStyle = new GUIStyle(GUI.skin.button);
                //{
                //	fixedHeight = 0,
                //};
            }

            if (property.Info.PropertyType != PropertyType.Method)
            {
                throw new ArgumentException("A method property drawer of type " + this.GetType().GetNiceName() + " cannot draw properties of type " + property.Info.PropertyType + ".");
            }

            var methodInfo = (MethodInfo)property.Info.MemberInfo;

            //
            // If method is not valid, render error message and return
            //

            var isValid = property.Context.Get(this, "IsValid", (bool?)null);

            if (!isValid.Value.HasValue)
            {
                isValid.Value = methodInfo.GetParameters().Length == 0;
            }

            if (!isValid.Value.Value)
            {
                var error = property.Context.Get(this, "Error", (string)null);

                if (error.Value == null)
                {
                    error.Value = "Cannot show button for method '" + methodInfo.DeclaringType.GetNiceName() + "." + methodInfo.GetNiceName() + "' in the inspector, because it does not have zero parameters.";
                }

                AllEditorGUI.ErrorMessageBox(error.Value);
                return;
            }

            //
            // Handle button style and label
            //

            GUIStyle style        = property.Context.GetGlobal("ButtonStyle", (GUIStyle)null).Value;
            var      buttonHeight = property.Context.GetGlobal("ButtonHeight", 0).Value;

            var buttonAttribute = property.Info.GetAttribute <ButtonAttribute>();

            if (buttonAttribute != null)
            {
                if (buttonHeight == 0 && buttonAttribute.ButtonHeight > 0)
                {
                    buttonHeight = buttonAttribute.ButtonHeight;
                    //buttonStyle.fixedHeight = buttonAttribute.ButtonHeight;
                    //style = buttonStyle;
                }

                if (buttonAttribute.Name != null)
                {
                    var mh = property.Context.Get(this, "ButtonStringMemberHelper", (StringMemberHelper)null);
                    if (mh.Value == null)
                    {
                        mh.Value = new StringMemberHelper(property.ParentType, buttonAttribute.Name);
                    }

                    if (mh.Value.ErrorMessage != null)
                    {
                        AllEditorGUI.ErrorMessageBox(mh.Value.ErrorMessage);
                    }

                    if (label == null)
                    {
                        label = new GUIContent(mh.Value.GetString(property));
                    }
                    else
                    {
                        label.text = mh.Value.GetString(property);
                    }
                }
            }
            if (style == null)
            {
                if (buttonHeight > 20)
                {
                    style = SirenixGUIStyles.Button;
                }
                else
                {
                    style = EditorStyles.miniButton;
                }
            }

            //
            // Render button and invoke
            //
            Rect btnRect = buttonHeight > 0 ?
                           GUILayoutUtility.GetRect(GUIContent.none, style, GUILayoutOptions.Height(buttonHeight)) :
                           GUILayoutUtility.GetRect(GUIContent.none, style);

            btnRect = EditorGUI.IndentedRect(btnRect);

            if (label == null)
            {
                label = GUIHelper.TempContent(property.Info.PropertyName.TitleCase_AddKongGe());
            }

            if (GUI.Button(btnRect, label, style))
            {
                GUIHelper.RemoveFocusControl();
                var caller = property.Context.Get(this, "MethodCaller", (Action <object>)null);

                if (caller.Value == null)
                {
                    caller.Value = EmitUtilities.CreateWeakInstanceMethodCaller(methodInfo);
                }

                var parentValueProperty = property.ParentValueProperty;
                var targets             = property.ParentValues;

                for (int i = 0; i < targets.Count; i++)
                {
                    object value = targets[i];

                    if (object.ReferenceEquals(value, null) == false)
                    {
                        try
                        {
                            caller.Value(value);
                        }
                        catch (ExitGUIException ex)
                        {
                            throw ex;
                        }
                        catch (Exception ex)
                        {
                            Debug.LogException(ex);
                        }

                        if (parentValueProperty != null && value.GetType().IsValueType)
                        {
                            // If it's a struct, it will have been boxed and the invoke call might
                            // have changed the struct and this won't be reflected in the original,
                            // unboxed source struct.

                            // Therefore, set the source value to the boxed struct that we just invoked on.
                            parentValueProperty.ValueEntry.WeakValues[i] = value;
                        }
                    }
                }
            }
        }
Beispiel #14
0
        /// <summary>
        /// Draws the property.
        /// </summary>
        protected override void DrawPropertyLayout(GUIContent label)
        {
            var property  = this.Property;
            var attribute = this.Attribute;

            if (property.Info.PropertyType == PropertyType.Method)
            {
                var methodContext = property.Context.Get(this, "Config", (MethodContext)null);

                if (methodContext.Value == null)
                {
                    methodContext.Value = new MethodContext();

                    MethodInfo methodInfo = property.Info.GetMemberInfo() as MethodInfo;

                    if (methodInfo == null)
                    {
                        methodInfo = property.Info.GetMethodDelegate().Method;
                    }

                    if (methodInfo.ReturnType != typeof(void))
                    {
                        methodContext.Value.ErrorMessage = "The method '" + methodInfo.Name + "' must have a return type of type void.";
                    }
                    else if (methodInfo.GetParameters().Length > 0)
                    {
                        methodContext.Value.ErrorMessage = "The method '" + methodInfo.Name + "' cannot take any parameters.";
                    }
                    else if (methodInfo.IsStatic)
                    {
                        var del = property.Info.GetMethodDelegate();

                        if (del == null)
                        {
                            methodContext.Value.StaticMethod = EmitUtilities.CreateStaticMethodCaller(methodInfo);
                        }
                        else
                        {
                            methodContext.Value.StaticMethod = (Action)del;
                        }
                    }
                    else
                    {
                        var del = property.Info.GetMethodDelegate();

                        if (del == null)
                        {
                            methodContext.Value.InstanceMethod = EmitUtilities.CreateWeakInstanceMethodCaller(methodInfo);
                        }
                        else
                        {
                            methodContext.Value.StaticMethod = () => del.DynamicInvoke();
                        }
                    }
                }

                if (methodContext.Value.ErrorMessage != null)
                {
                    SirenixEditorGUI.ErrorMessageBox(methodContext.Value.ErrorMessage);
                }
                else
                {
                    if (methodContext.Value.InstanceMethod != null)
                    {
                        methodContext.Value.InstanceMethod(property.ParentValues[0]);
                    }
                    else
                    {
                        methodContext.Value.StaticMethod();
                    }
                }
            }
            else
            {
                if (attribute.PrependMethodName != null)
                {
                    this.DoInspectorGUI(property, "Prepend", attribute.PrependMethodName);
                }

                this.CallNextDrawer(label);

                if (attribute.AppendMethodName != null)
                {
                    this.DoInspectorGUI(property, "Append", attribute.AppendMethodName);
                }
            }
        }