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); }
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); }
/// <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 }
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 }
/// <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 }
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 }
/// <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); } } }
/// <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); }
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); }
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 }
private void OnMenuItemClicked(PopupMenuItem item) { onMenuItemClicked(item); Close(); }
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); }
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)); }
private void OnPopupMenuItemClicked([NotNull] PopupMenuItem item) { SetValueFromType(item.type); }
private void OnTargetTypeMenuItemClicked(PopupMenuItem item) { Select(ReasonSelectionChanged.Initialization); OnTargetTypeChanged((Type)item.IdentifyingObject, false, null); }