/************************************************************************************************************************/

        private static void DoGetSetToggleGUI(ref Rect area, MethodBase method)
        {
            // Check if the method name starts with "get_" or "set_".
            // Check the underscore first since it's hopefully the rarest so it can break out early.

            var name = method.Name;

            if (name.Length <= 4 || name[3] != '_' || name[2] != 't' || name[1] != 'e')
            {
                return;
            }

            var first = name[0];
            var isGet = first == 'g';
            var isSet = first == 's';

            if (!isGet && !isSet)
            {
                return;
            }

            var methodName             = (isGet ? "set_" : "get_") + name.Substring(4, name.Length - 4);
            var oppositePropertyMethod = method.DeclaringType.GetMethod(methodName, UltEventUtils.AnyAccessBindings);

            if (oppositePropertyMethod == null ||
                (isGet && !MethodSelectionMenu.IsSupported(method.GetReturnType())))
            {
                return;
            }

            area.width -= GetSetWidth + Padding;

            var buttonArea = new Rect(
                area.x + area.width + Padding,
                area.y,
                GetSetWidth,
                area.height);

            if (GUI.Button(buttonArea, isGet ? "Get" : "Set"))
            {
                var cachedState = new DrawerState();
                cachedState.CopyFrom(DrawerState.Current);

                EditorApplication.delayCall += () =>
                {
                    DrawerState.Current.CopyFrom(cachedState);

                    SetMethod(oppositePropertyMethod);

                    DrawerState.Current.Clear();

                    InternalEditorUtility.RepaintAllViews();
                };
            }
        }
예제 #2
0
        private void DelayedRemoveCall(int index)
        {
            var list  = _CurrentCallList;
            var state = new DrawerState();

            state.CopyFrom(DrawerState.Current);

            EditorApplication.delayCall += () =>
            {
                DrawerState.Current.CopyFrom(state);

                RemoveCall(list, index);

                DrawerState.Current.UpdateLinkedArguments();
                DrawerState.Current.Clear();

                InternalEditorUtility.RepaintAllViews();
            };
        }
        /************************************************************************************************************************/
        #endregion
        /************************************************************************************************************************/
        #region Entry Point
        /************************************************************************************************************************/

        /// <summary>Opens the menu near the specified `area`.</summary>
        public static void ShowMenu(Rect area)
        {
            CachedState.CopyFrom(DrawerState.Current);

            _CurrentMethod = CachedState.call.GetMethodSafe();
            _Bindings      = GetBindingFlags();
            _Menu          = new GenericMenu();

            BoolPref.AddDisplayOptions(_Menu);

            Object[] targetObjects;
            var      targets = GetObjectReferences(CachedState.TargetProperty, out targetObjects);

            AddCoreItems(targets);

            // Populate the main contents of the menu.
            {
                if (targets == null)
                {
                    var    serializedMethodName = CachedState.MethodNameProperty.stringValue;
                    Type   declaringType;
                    string methodName;
                    PersistentCall.GetMethodDetails(serializedMethodName, null, out declaringType, out methodName);

                    // If we have no target, but do have a type, populate the menu with that type's statics.
                    if (declaringType != null)
                    {
                        PopulateMenuWithStatics(targetObjects, declaringType);

                        goto ShowMenu;
                    }
                    else// If we have no type either, pretend the inspected objects are the targets.
                    {
                        targets = targetObjects;
                    }
                }

                // Ensure that all targets share the same type.
                var firstTarget = ValidateTargetsAndGetFirst(targets);
                if (firstTarget == null)
                {
                    targets     = targetObjects;
                    firstTarget = targets[0];
                }

                // Add menu items according to the type of the target.
                if (firstTarget is GameObject)
                {
                    PopulateMenuForGameObject("", false, targets);
                }
                else if (firstTarget is Component)
                {
                    PopulateMenuForComponent(targets);
                }
                else
                {
                    PopulateMenuForObject(targets);
                }
            }

ShowMenu:

            _Menu.DropDown(area);

            GC.Collect();
        }
        /************************************************************************************************************************/

        private static void DoMethodNameSuggestionGUI(ref Rect area, Type declaringType, string methodName)
        {
            if (declaringType == null ||
                string.IsNullOrEmpty(methodName))
            {
                return;
            }

            var lastDot = methodName.LastIndexOf('.');

            if (lastDot >= 0)
            {
                lastDot++;
                if (lastDot >= methodName.Length)
                {
                    return;
                }

                methodName = methodName.Substring(lastDot);
            }

            var methods = declaringType.GetMethods(UltEventUtils.AnyAccessBindings);

            if (methods.Length == 0)
            {
                return;
            }

            area.width -= SuggestionButtonWidth + Padding;

            var buttonArea = new Rect(
                area.x + area.width + Padding,
                area.y,
                SuggestionButtonWidth,
                area.height);

            if (GUI.Button(buttonArea, MethodNameSuggestionLabel))
            {
                var cachedState = new DrawerState();
                cachedState.CopyFrom(DrawerState.Current);

                EditorApplication.delayCall += () =>
                {
                    DrawerState.Current.CopyFrom(cachedState);

                    var bestMethod   = methods[0];
                    var bestDistance = UltEventUtils.CalculateLevenshteinDistance(methodName, bestMethod.Name);

                    var i = 1;
                    for (; i < methods.Length; i++)
                    {
                        var method   = methods[i];
                        var distance = UltEventUtils.CalculateLevenshteinDistance(methodName, method.Name);

                        if (bestDistance > distance)
                        {
                            bestDistance = distance;
                            bestMethod   = method;
                        }
                    }

                    SetMethod(bestMethod);

                    DrawerState.Current.Clear();

                    InternalEditorUtility.RepaintAllViews();
                };
            }
        }