private void TryCreatePopupMenuItem(ref List <PopupMenuItem> menuItems, int itemIndex)
        {
            var objs     = history[itemIndex];
            int objCount = objs.Length;

            if (objCount == 0)
            {
                return;
            }
            var obj = objs[0];

            if (obj == null)
            {
                return;
            }

            string name = objCount == 1 ? obj.name : StringUtils.NamesToString(objs);

                        #if UNITY_EDITOR
            var mainObject = obj.GetAssetOrMainComponent();
            var preview    = UnityEditor.AssetPreview.GetMiniThumbnail(mainObject);
                        #else
            Texture2D preview = null;
                        #endif

            var item = PopupMenuItem.Item(itemIndex, objs.GetType(), name, objCount == 1 ? obj.HierarchyOrAssetPath() : "", null, preview);
            menuItems.Add(item);
        }
Beispiel #2
0
        public void Setup(IInspector setInspector, List <PopupMenuItem> setItems, Dictionary <string, PopupMenuItem> setGroupsByLabel, Dictionary <string, PopupMenuItem> setItemsByLabel, Rect openPosition, Action <PopupMenuItem> setOnMenuItemClicked, Action setOnClosed, GUIContent setLabel)
        {
            inspector = null;

            label = setLabel;

            //TO DO: Set active item using current value for fields
            activeGroup = null;

            itemsFiltered.Clear();
            lastAppliedFilter = "";

            filter                   = "";
            setFilter                = "";
            currentViewLabel.text    = label.text;
            currentViewLabel.tooltip = label.tooltip;

            onClosed            = setOnClosed;
            onMenuItemClicked   = setOnMenuItemClicked;
            inspector           = setInspector;
            rootItems           = setItems;
            groupsByLabel       = setGroupsByLabel;
            itemsByLabel        = setItemsByLabel;
            searchableListBuilt = false;

            RebuildIntructionsInChildren();

            Open(openPosition);
        }
Beispiel #3
0
        /// <inheritdoc />
        protected override void OnPopupMenuItemClicked(PopupMenuItem item)
        {
            if (string.Equals(item.label, SelectNoneMenuItemLabel))
            {
                Value = Value.ClearFlags();
                return;
            }

            var setValue = item.IdentifyingObject as Enum;

            if (setValue.Equals(DefaultValue()))
            {
                Value = setValue;
                return;
            }

            if (!hasFlagsAttribute)
            {
                Value = setValue;
                return;
            }

            var valueWas = Value;

            if (valueWas.HasFlag(setValue))
            {
                Value = valueWas.RemoveFlag(setValue);
            }
            else
            {
                Value = valueWas.SetFlag(setValue);
            }
        }
		public static void BuildPopupMenuItemForTypeWithLabel(ref List<PopupMenuItem> rootItems, ref Dictionary<string, PopupMenuItem> groupsByLabel, ref Dictionary<string, PopupMenuItem> itemsByLabel, [NotNull]Type type, string fullMenuName)
		{
			#if DEV_MODE || PROFILE_POWER_INSPECTOR
			Profiler.BeginSample("BuildPopupMenuItemForTypeWithLabel");
			#endif

			int split = fullMenuName.LastIndexOf('/');
			PopupMenuItem item;
			if(split != -1)
			{
				var groupLabels = fullMenuName.Substring(0, split);
				var itemLabel = fullMenuName.Substring(split + 1);
				var group = GetOrCreateGroup(ref rootItems, ref groupsByLabel, groupLabels, null);
				item = group.AddChild(itemLabel, GetTooltip(type), type);
			}
			else
			{
				item = PopupMenuItem.Item(type, fullMenuName, GetTooltip(type), null);
				rootItems.Add(item);
			}

			if(!itemsByLabel.ContainsKey(fullMenuName))
			{
				itemsByLabel.Add(fullMenuName, item);
			}
			#if DEV_MODE
			else { Debug.LogWarning("itemsByLabel already contained key \""+fullMenuName+"\"."); }
			#endif
			
			#if DEV_MODE || PROFILE_POWER_INSPECTOR
			Profiler.EndSample();
			#endif
		}
Beispiel #5
0
        private static readonly HashSet <string> MenuLabels        = new HashSet <string>(); //new HashSet<string>(9000);

        /// <summary>
        /// Get list of all visible types and hidden types accessible from given context
        /// </summary>
        /// <param name="rootItems"> [in,out] The root items in the menu. </param>
        /// <param name="groupsByLabel">[in,out] Any built groups will be added to the list with their full label as key. </param>
        /// <param name="itemsByLabel">[in,out] Built item will be added to the list with ther full label as key. </param>
        /// <param name="typeContext">
        /// Context for the type. This may be null. </param>
        /// <param name="addNull"> True to add null. </param>
        public static void BuildTypePopupMenuItemsForContext(ref List <PopupMenuItem> rootItems, ref Dictionary <string, PopupMenuItem> groupsByLabel, ref Dictionary <string, PopupMenuItem> itemsByLabel, [CanBeNull] Type typeContext, bool addNull)
        {
                        #if DEV_MODE || PROFILE_POWER_INSPECTOR
            Profiler.BeginSample("BuildTypePopupMenuItemsForContext");
                        #endif

            var menuDrawer = PopupMenu.instance;
            if (menuDrawer != null)
            {
                if (menuDrawer.builtFromTypeContext == typeContext)
                {
                    rootItems     = menuDrawer.rootItems;
                    groupsByLabel = menuDrawer.groupsByLabel;
                    itemsByLabel  = menuDrawer.itemsByLabel;
                    return;
                }
                PopupMenu.instance.DisposeItems();
            }

            string[] typeLabels;
            var      types = GenerateTypesVisibleFromContext(typeContext, out typeLabels);
            int      count = types.Length;

            for (int n = 0; n < count; n++)
            {
                var label = typeLabels[n];

                // Sometimes multiple assemblies can contain types with exact same full name. Skip these duplicates.
                if (MenuLabels.Add(label))
                {
                    BuildPopupMenuItemForTypeWithLabel(ref rootItems, ref groupsByLabel, ref itemsByLabel, types[n], label);
                }
            }

            // NOTE: do not dispose types or typeLabels
            // since they are cached and reused by PopupMenu!
            //ArrayPool<Type>.Dispose(ref types);
            //ArrayPool<string>.Dispose(ref typeLabels);

            rootItems.Sort();
            for (int n = rootItems.Count - 1; n >= 0; n--)
            {
                rootItems[n].Sort();
            }

            if (addNull && MenuLabels.Add("None"))
            {
                var nullItem = PopupMenuItem.Item(null as Type, "None", "A null reference; one that does not refer to any object.", null);
                nullItem.Preview = null;
                rootItems.Insert(0, nullItem);
                itemsByLabel.Add(nullItem.label, nullItem);
            }

            MenuLabels.Clear();

                        #if DEV_MODE || PROFILE_POWER_INSPECTOR
            Profiler.EndSample();
                        #endif
        }
Beispiel #6
0
 /// <summary> Called when an item in the popup menu is clicked. </summary>
 /// <param name="item"> Information about clicked item. </param>
 protected virtual void OnPopupMenuItemClicked(PopupMenuItem item)
 {
     try
     {
         Value = (TValue)item.IdentifyingObject;
     }
     catch (Exception e)
     {
         Debug.LogError("Failed to cast item IdentifyingObject from type " + StringUtils.TypeToString(item.IdentifyingObject) + " to " + StringUtils.ToString(typeof(TValue)) + ": " + e);
     }
 }
		public static void BuildPopupMenuItemWithLabel([NotNull]ref List<PopupMenuItem> rootItems, [NotNull]ref Dictionary<string, PopupMenuItem> groupsByLabel, [NotNull]ref Dictionary<string, PopupMenuItem> itemsByLabel, [NotNull]object value, [CanBeNull]Type type, [NotNullOrEmpty]string fullMenuName, [NotNull]string tooltip, MenuItemValueType valueType)
		{
			#if DEV_MODE || PROFILE_POWER_INSPECTOR
			Profiler.BeginSample("BuildPopupMenuItemWithLabel");
			#endif
	
			#if DEV_MODE && PI_ASSERTATIONS
			Debug.Assert(rootItems != null);
			Debug.Assert(groupsByLabel != null);
			Debug.Assert(itemsByLabel != null);
			Debug.Assert(value != null);
			Debug.Assert(!string.IsNullOrEmpty(fullMenuName));
			Debug.Assert(!fullMenuName.EndsWith("/"));
			Debug.Assert(!fullMenuName.StartsWith("/"));
			Debug.Assert(tooltip != null);
			#endif

			int split = fullMenuName.LastIndexOf('/');
			PopupMenuItem item;
			if(split != -1)
			{
				if(split == fullMenuName.Length - 1)
				{
					Debug.LogWarning("BuildPopupMenuItemWithLabel called with menu path that ended with \"/\". Menu items with an empty name are not supported.");
					#if DEV_MODE || PROFILE_POWER_INSPECTOR
					Profiler.EndSample();
					#endif
					return;
				}

				var groupLabel = fullMenuName.Substring(0, split);
				var itemLabel = fullMenuName.Substring(split + 1);

				var group = GetOrCreateGroup(ref rootItems, ref groupsByLabel, groupLabel, null);
				item = group.AddChild(itemLabel, tooltip, value, type, valueType);
			}
			else
			{
				item = PopupMenuItem.Item(value, type, fullMenuName, tooltip, null, valueType);
				rootItems.Add(item);
			}

			if(!itemsByLabel.ContainsKey(fullMenuName))
			{
				itemsByLabel.Add(fullMenuName, item);
			}
			#if DEV_MODE
			else { Debug.LogError("Menu already contained item by name \"" + fullMenuName + "\""); }
			#endif
			
			#if DEV_MODE || PROFILE_POWER_INSPECTOR
			Profiler.EndSample();
			#endif
		}
Beispiel #8
0
        private void SetActiveItem(PopupMenuItem value)
        {
                        #if DEV_MODE || PROFILE_POWER_INSPECTOR
            Profiler.BeginSample("PopupMenu.SetActiveItem");
                        #endif

            activeGroup = value;
            UpdateCurrentViewLabel();
            RebuildIntructionsInChildren();
            GUI.changed = true;

                        #if DEV_MODE || PROFILE_POWER_INSPECTOR
            Profiler.EndSample();
                        #endif
        }
Beispiel #9
0
        /// <inheritdoc />
        protected override void GenerateMenuItems(ref List <PopupMenuItem> rootItems, ref Dictionary <string, PopupMenuItem> groupsByLabel, ref Dictionary <string, PopupMenuItem> itemsByLabel)
        {
            PopupMenuUtility.BuildPopupMenuItemsForEnumType(ref rootItems, ref groupsByLabel, ref itemsByLabel, typeContext);

            if (AddClearAllMenuItem())
            {
                // only add if menu doesn't already contain entry by name
                if (!itemsByLabel.ContainsKey(SelectNoneMenuItemLabel))
                {
                    var item = PopupMenuItem.Item(null as Type, SelectNoneMenuItemLabel, "0", null);
                    rootItems.Insert(0, item);
                    itemsByLabel.Add(SelectNoneMenuItemLabel, item);
                }
            }
        }
Beispiel #10
0
        /// <summary> Gets group at given path. If group or any of its parents don't yet exist, creates them. </summary>
        /// <param name="rootItems"> [in,out] The root items of the popup menu. If a new group is created it can get added here. </param>
        /// <param name="groupsByLabel"> [in,out] All groups currently existing in the menu, flattened, with full menu path as key in dictionary. </param>
        ///  <param name="fullMenuPath"> The full path to the menu item, where nested groups are separated by the slash ('/') character. </param>
        /// <param name="icon"> The icon to use for the group if existing is not found and a new is created. </param>
        /// <returns> The or create group. </returns>
        private static PopupMenuItem GetOrCreateGroup(ref List <PopupMenuItem> rootItems, ref Dictionary <string, PopupMenuItem> groupsByLabel, string fullMenuPath, Texture icon)
        {
                        #if DEV_MODE || PROFILE_POWER_INSPECTOR
            Profiler.BeginSample("GetOrCreateGroup");
                        #endif

            PopupMenuItem result;
            if (groupsByLabel.TryGetValue(fullMenuPath, out result))
            {
                return(result);
            }

            int parentGroupEnd = fullMenuPath.LastIndexOf('/');
            //if nested group
            if (parentGroupEnd != -1)
            {
                var parentGroup = GetOrCreateGroup(ref rootItems, ref groupsByLabel, fullMenuPath.Substring(0, parentGroupEnd), icon);
                result = PopupMenuItem.Group(fullMenuPath.Substring(parentGroupEnd + 1), "", parentGroup, icon);
                parentGroup.children.Add(result);
            }
            //if root group
            else
            {
                result = PopupMenuItem.Group(fullMenuPath, "", null, icon);
                rootItems.Add(result);
            }

            if (!groupsByLabel.ContainsKey(fullMenuPath))
            {
                groupsByLabel.Add(fullMenuPath, result);
            }
                        #if DEV_MODE
            else
            {
                Debug.LogError("Menu already contained group by name \"" + fullMenuPath + "\"");
            }
                        #endif

                        #if DEV_MODE || PROFILE_POWER_INSPECTOR
            Profiler.EndSample();
                        #endif
            return(result);
        }
        private void OnMenuItemClickNextLayout(PopupMenuItem item)
        {
            var inspector = PopupMenuManager.LastmenuOpenedForInspector;

            int itemIndex = (int)item.IdentifyingObject;
            var e         = Event.current;

            //ctrl + click can be used to open item in other split view
            if (e != null && e.control && inspector.InspectorDrawer.CanSplitView)
            {
                var splittable = inspector.InspectorDrawer as ISplittableInspectorDrawer;
                if (splittable != null && inspector == splittable.MainView)
                {
                    ShowInSplitView(splittable, itemIndex);
                    return;
                }
            }

            Show(inspector, itemIndex);
        }
Beispiel #12
0
        public static PopupMenuItem BuildPopupMenuItemWithLabel(ref List <PopupMenuItem> rootItems, ref Dictionary <string, PopupMenuItem> groupsByLabel, ref Dictionary <string, PopupMenuItem> itemsByLabel, [NotNull] object value, [CanBeNull] Type type, string fullMenuName, string tooltip, [CanBeNull] Texture preview)
        {
                        #if DEV_MODE || PROFILE_POWER_INSPECTOR
            Profiler.BeginSample("BuildPopupMenuItemWithLabel");
                        #endif

            int split = fullMenuName.LastIndexOf('/');

            PopupMenuItem item;
            if (split != -1)
            {
                var groupLabels = fullMenuName.Substring(0, split);
                var itemLabel   = fullMenuName.Substring(split + 1);
                var group       = GetOrCreateGroup(ref rootItems, ref groupsByLabel, groupLabels, InspectorUtility.Preferences.graphics.PrefabIcon);
                item = PopupMenuItem.Item(value, type, itemLabel, tooltip, null, preview);
                group.AddChild(item);
            }
            else
            {
                item = PopupMenuItem.Item(value, type, fullMenuName, tooltip, null, preview);
                rootItems.Add(item);
            }

            if (!itemsByLabel.ContainsKey(fullMenuName))
            {
                itemsByLabel.Add(fullMenuName, item);
            }
                        #if DEV_MODE
            else
            {
                Debug.LogError("Menu already contained item by name \"" + fullMenuName + "\"");
            }
                        #endif

                        #if DEV_MODE || PROFILE_POWER_INSPECTOR
            Profiler.EndSample();
                        #endif

            return(item);
        }
Beispiel #13
0
        public static Menu BuildRightClickMenu(PopupMenuItem item)
        {
            var menu = Menu.Create();

                        #if !POWER_INSPECTOR_LITE
            menu.Add("Copy", () => CopyToClipboard(item));
                        #endif

                        #if UNITY_EDITOR
            if (item.type != null)
            {
                if (item.type.IsComponent())
                {
                    if (Types.MonoBehaviour.IsAssignableFrom(item.type))
                    {
                        menu.Add("Ping", () => PingMonoScriptAsset(item.type));
                    }
                }
            }
                        #endif
            return(menu);
        }
        private static void OnMenuItemClicked(PopupMenuItem item)
        {
            var target = currentMenuTarget;

            currentMenuTarget = null;

            var method = item.IdentifyingObject as MethodInfo;

                        #if DEV_MODE
            Debug.Assert(method.ReturnType != typeof(IEnumerator) || Application.isPlaying);
                        #endif

                        #if UNITY_EDITOR
            if (!Application.isPlaying)
            {
                if (target == null || !target.RunsInEditMode())
                {
                    if (InspectorUtility.Preferences.warnAboutInvokingInEditMode && !EditorUtility.DisplayDialog("Execute In Edit Mode?", "Execute method " + method.Name + " in edit mode? This might not work properly for all methods.", "Execute", "Cancel"))
                    {
                        return;
                    }
                }
            }
                        #endif

                        #if UNITY_EDITOR
            Undo.RegisterFullObjectHierarchyUndo(method.IsStatic ? null : target, method.Name);
                        #endif

            if (method.ReturnType == typeof(IEnumerator))
            {
                (target as MonoBehaviour).StartCoroutine(method.Name);
                return;
            }

            method.Invoke(method.IsStatic ? null : target, null);
        }
        /// <inheritdoc />
        protected override void GenerateMenuItems(ref List <PopupMenuItem> rootItems, ref Dictionary <string, PopupMenuItem> groupsByLabel, ref Dictionary <string, PopupMenuItem> itemsByLabel)
        {
                        #if DEV_MODE || PROFILE_POWER_INSPECTOR
            Profiler.BeginSample("ConstraintedTypeDrawer.GenerateMenuItems");
                        #endif

            var types = TypeExtensions.GetAllTypesThreadSafe(true, false, false);

            if (typeCategoryConstraint.HasFlag(TypeConstraint.Struct))
            {
                types = types.Where((t) => t.IsValueType && t != typeof(Nullable <>));
            }
            else
            {
                if (typeCategoryConstraint.HasFlag(TypeConstraint.Class))
                {
                    types = types.Where((t) => !t.IsValueType);
                }

                if (typeCategoryConstraint.HasFlag(TypeConstraint.New))
                {
                    types = types.Where((t) => t.GetConstructor(Type.EmptyTypes) != null);
                }
            }

            switch (baseTypeConstraints.Length)
            {
            case 0:
                foreach (var type in types)
                {
                    PopupMenuUtility.BuildPopupMenuItemForTypeWithLabel(ref rootItems, ref groupsByLabel, ref itemsByLabel, type, TypeExtensions.GetPopupMenuLabel(type));
                }
                break;

            case 1:
                foreach (var type in types)
                {
                    if (baseTypeConstraints[0].IsAssignableFrom(type))
                    {
                        PopupMenuUtility.BuildPopupMenuItemForTypeWithLabel(ref rootItems, ref groupsByLabel, ref itemsByLabel, type, TypeExtensions.GetPopupMenuLabel(type));
                    }
                    break;
                }
                break;

            default:
                foreach (var type in types)
                {
                    bool assignable = true;
                    for (int n = baseTypeConstraints.Length - 1; n >= 0; n--)
                    {
                        if (!baseTypeConstraints[n].IsAssignableFrom(type))
                        {
                            assignable = false;
                            break;
                        }
                    }
                    if (assignable)
                    {
                        PopupMenuUtility.BuildPopupMenuItemForTypeWithLabel(ref rootItems, ref groupsByLabel, ref itemsByLabel, type, TypeExtensions.GetPopupMenuLabel(type));
                    }
                }
                break;
            }

            rootItems.Sort();
            for (int n = rootItems.Count - 1; n >= 0; n--)
            {
                rootItems[n].Sort();
            }

            var nullItem = PopupMenuItem.Item(null as Type, "None", "A null reference; one that does not refer to any object.", null);
            nullItem.Preview = null;
            rootItems.Insert(0, nullItem);
            itemsByLabel.Add(nullItem.label, nullItem);

                        #if DEV_MODE || PROFILE_POWER_INSPECTOR
            Profiler.EndSample();
                        #endif
        }
Beispiel #16
0
 private void OnMenuItemClicked(PopupMenuItem item)
 {
     onMenuItemClicked(item);
     Close();
 }
Beispiel #17
0
        public static bool Draw(Rect position, bool selected, [NotNull] PopupMenuItem item)
        {
            float previewSize = 17f;

            var buttonRect = position;

            buttonRect.x     += previewSize;
            buttonRect.width -= previewSize;

            if (drawWithFullPath)
            {
                DrawLabel.text = item.FullLabel('.');
            }
            else
            {
                DrawLabel.text = item.label;
            }
            DrawLabel.tooltip = item.secondaryLabel;

            bool itemClicked = false;

            if (GUI.Button(buttonRect, DrawLabel, selected ? DrawGUI.richTextLabelWhite : DrawGUI.richTextLabel))
            {
                if (Event.current.button == 0)
                {
                    Debug.Log(item + " - GUI.Button clicked");
                    itemClicked = true;
                    DrawGUI.Use(Event.current);
                    GUI.changed = true;
                }
                else if (Event.current.button == 1)
                {
                    var menu = BuildRightClickMenu(item);
                    menu.Open();
                    DrawGUI.Use(Event.current);
                    GUI.changed = true;
                }
            }

            var preview = item.Preview;

            if (preview != null)
            {
                var iconRect = buttonRect;
                iconRect.width  = previewSize;
                iconRect.height = previewSize;
                iconRect.x     -= previewSize;
                GUI.DrawTexture(iconRect, preview, ScaleMode.ScaleToFit);
            }

            if (item.IsGroup)
            {
                var arrowRect = buttonRect;
                arrowRect.x     += buttonRect.width - previewSize;
                arrowRect.y     += 2f;
                arrowRect.width  = 13f;
                arrowRect.height = 13f;

                GUI.Label(arrowRect, GUIContent.none, "AC RightArrow");
            }

            return(itemClicked);
        }
Beispiel #18
0
 private static void CopyToClipboard(PopupMenuItem item)
 {
     Clipboard.Copy(item.type, Types.Type);
     Clipboard.SendCopyToClipboardMessage(item.label);
 }
 private void OnMenuItemClick(PopupMenuItem item)
 {
     //new test: delaying action until next frame, so that can detect modifiers
     PopupMenuManager.LastmenuOpenedForInspector.OnNextLayout(() => OnMenuItemClickNextLayout(item));
 }
Beispiel #20
0
 private void OnPopupMenuItemClicked([NotNull] PopupMenuItem item)
 {
     SetValueFromType(item.type);
 }
 private void OnTargetTypeMenuItemClicked(PopupMenuItem item)
 {
     Select(ReasonSelectionChanged.Initialization);
     OnTargetTypeChanged((Type)item.IdentifyingObject, false, null);
 }