private static void RegisterComponentHiddenInMenu(Type type) { if (type.IsDefined(Types.DisallowMultipleComponent, false)) { AddComponentUtility.AddDisallowMultiple(type); } if (type.IsDefined(OnlyComponentAttribute, true)) { AddComponentUtility.AddOnlyComponent(type); } }
public void UpdateVisibleMembers() { GUI.changed = true; int count = lastVisibleIndex - firstVisibleIndex + 1; DrawerArrayPool.Resize(ref visibleMembers, count); for (int n = count - 1; n >= 0; n--) { var member = members[firstVisibleIndex + n]; visibleMembers[n] = member; visibleMembersHaveConflicts[n] = AddComponentUtility.HasConflictingMembers(member.Type, target); } }
private static void Add(Type type, string fullMenuName) { if (type.IsDefined(Types.DisallowMultipleComponent, false)) { AddComponentUtility.AddDisallowMultiple(type); } if (type.IsDefined(OnlyComponentAttribute, true)) { AddComponentUtility.AddOnlyComponent(type); } int split = fullMenuName.LastIndexOf('/'); if (split == -1) { #if DEV_MODE Debug.LogWarning("Adding type " + type.Name + " with fullMenuName \"" + fullMenuName + "\" to root"); #endif GetOrCreateRootItem(fullMenuName, type); } else { var groupLabels = fullMenuName.Substring(0, split); var itemLabel = fullMenuName.Substring(split + 1); //TEMP #if DEV_MODE if (fullMenuName.StartsWith("Unity Engine/", StringComparison.Ordinal) || fullMenuName.StartsWith("Unity Editor/", StringComparison.Ordinal)) { Debug.LogError("Creating Group \"" + fullMenuName.Substring(13) + "\" for type " + type.FullName + " with fullMenuName \"" + fullMenuName + "\" and assembly " + type.Assembly.GetName().Name + "."); } #endif var group = GetOrCreateGroup(groupLabels, null); group.AddChild(itemLabel, type); pathBuilder.Clear(); } }
public void AddComponent(Type type) { conflictingMembers.Clear(); AddComponentUtility.GetConflictingMembers(type, target, ref conflictingMembers); int conflictCount = conflictingMembers.Count; #if DEV_MODE Debug.Log(GetType().Name + ".AddComponent(" + (type == null ? "null" : type.Name) + ") called with conflictCount=" + conflictCount + "!"); #endif bool viewWasLocked = inspector.State.ViewIsLocked; if (conflictCount == 0) { if (OnComponentAdded != null) { OnComponentAdded(type); } target.AddComponent(type, true); Close(); return; } if (type == typeof(Transform)) { var gameObjectDrawers = inspector.State.drawers.Members; for (int d = gameObjectDrawers.Length - 1; d >= 0; d--) { var gameObjectDrawer = gameObjectDrawers[d] as IGameObjectDrawer; if (gameObjectDrawer != null) { var gameObjects = gameObjectDrawer.GameObjects; for (int g = gameObjectDrawers.Length - 1; g >= 0; g--) { var gameObject = gameObjects[g]; var rectTransform = gameObject.GetComponent <RectTransform>(); if (rectTransform != null) { Platform.Active.Destroy(rectTransform); } } } } Close(); return; } string header; string msg; string ok; if (conflictCount == 1) { header = "Conflicting Component"; msg = "Component " + type.Name + " cannot be added because it conflicts with existing Component " + conflictingMembers[0].Type.Name; ok = "Replace Existing"; } else { header = "Conflicting Components"; msg = "Component " + type.Name + " cannot be added because it conflicts with the following exiting Components:" + conflictingMembers[0].Name; foreach (var member in conflictingMembers) { msg += "\n" + member.Type.Name; } ok = "Replace " + conflictCount + " Existing"; } if (DrawGUI.Active.DisplayDialog(header, msg, ok, "Cancel")) { inspector.State.ViewIsLocked = true; foreach (var member in conflictingMembers) { var values = member.GetValues(); for (int n = values.Length - 1; n >= 0; n--) { var comp = values[n] as Component; Platform.Active.Destroy(comp); } } if (OnComponentAdded != null) { OnComponentAdded(type); } target.AddComponent(type, true); inspector.State.ViewIsLocked = viewWasLocked; Close(); } }
private static void GenerateItems() { itemsGenerated = true; AddComponentUtility.BuildConflictingTypesDictionaryIfDoesNotExist(); var assemblies = AppDomain.CurrentDomain.GetAssemblies(); int assemblyCount = assemblies.Length; rootGroups = new AddComponentMenuItem[0]; Apply(InspectorUtility.Preferences.addComponentMenuConfig); var componentTypes = TypeExtensions.ComponentTypes; for (int n = componentTypes.Length - 1; n >= 0; n--) { var type = componentTypes[n]; if (type.IsAbstract || type.IsGenericTypeDefinition || type.IsBaseComponentType()) { continue; } // All GameObjects will always already have a Transform or RectTransform component // and only one can be added to a GameObject, so don't show them in the menu. if (type == Types.Transform || type == Types.RectTransform) { continue; } if (Contains(type)) { continue; } //hide obsolete items from the menu if (type.IsDefined(Types.ObsoleteAttribute, false)) { #if DEV_MODE && DEBUG_SKIP_ADDING Debug.LogWarning("Skipping adding " + type.Name + " to Add Component menu because it has the Obsolete attribute"); #endif continue; } Add(type); } itemsByLabel.Clear(); for (int n = rootGroups.Length - 1; n >= 0; n--) { rootGroups[n].GetClassLabelsFlattened(ref pathBuilder, ref itemsByLabel); } if (searchableList != null) { SearchableListPool.Dispose(ref searchableList); } searchableList = SearchableListPool.Create(pathBuilder.ToArray()); pathBuilder.Clear(); // if add component menu config contains any invalid items, remove them RemoveInvalidItems(ref rootGroups); Sort(rootGroups); }
/// <inheritdoc /> protected override void BuildContextMenu(ref Menu menu, bool extendedMenu) { var addHistory = AddComponentHistoryTracker.LastAddedComponents; Type typeFromClipboard = null; if (Clipboard.CanPasteAs(Types.Type)) { #if DEV_MODE Debug.Log("Clipboard.CanPasteAs(Type): " + StringUtils.True); #endif typeFromClipboard = Clipboard.Paste <Type>(); #if DEV_MODE Debug.Log(Msg("typeFromClipboard: ", typeFromClipboard)); #endif } if (typeFromClipboard == null) { #if DEV_MODE Debug.Log("Clipboard.CanPasteAs(Type): " + StringUtils.False); #endif var objectReference = Clipboard.ObjectReference; #if DEV_MODE Debug.Log(Msg("objectReference: ", objectReference)); #endif if (objectReference != null) { #if UNITY_EDITOR var script = objectReference as UnityEditor.MonoScript; if (script != null) { typeFromClipboard = script.GetClass(); } else #endif { typeFromClipboard = objectReference.GetType(); } #if DEV_MODE Debug.Log(Msg("typeFromClipboard: ", typeFromClipboard)); #endif } } var gameObjectDrawer = parent as GameObjectDrawer; if (typeFromClipboard != null && typeFromClipboard.IsComponent()) { addHistory.Remove(typeFromClipboard); if (!AddComponentUtility.HasConflictingMembers(typeFromClipboard, gameObjectDrawer)) { menu.Add(typeFromClipboard.Name, () => QuickAddComponent(typeFromClipboard)); } else { menu.AddDisabled(typeFromClipboard.Name); } if (addHistory.Count > 0) { menu.AddSeparator(); } } for (int n = 0, count = addHistory.Count; n < count; n++) { var type = addHistory[n]; if (!AddComponentUtility.HasConflictingMembers(type, gameObjectDrawer)) { menu.Add(type.Name, () => QuickAddComponent(type)); } else { menu.AddDisabled(type.Name); } } }
private static void GenerateItems() { itemsGenerated = true; AddComponentUtility.BuildConflictingTypesDictionaryIfDoesNotExist(); var assemblies = AppDomain.CurrentDomain.GetAssemblies(); int assemblyCount = assemblies.Length; rootGroups = new AddComponentMenuItem[0]; Apply(InspectorUtility.Preferences.addComponentMenuConfig); var componentTypes = TypeExtensions.ComponentTypes; for (int n = componentTypes.Length - 1; n >= 0; n--) { var type = componentTypes[n]; if (type.IsAbstract || type.IsGenericTypeDefinition) { continue; } //Special case. For some reason Unity didn't make these abstract //but they still should not be shown in the Add Component menu if (type == Types.MonoBehaviour || type == Types.Effector2D || type == Types.Behaviour || type == Types.Collider || type == Types.Collider2D || type == Types.Renderer #if !UNITY_2019_3_OR_NEWER || type == Types.GUIElement #endif || type == Types.Joint || type == Types.Joint2D || type == Types.AnchoredJoint2D || type == Types.PhysicsUpdateBehaviour2D || type == Types.Tree || type == Types.ParticleSystemRenderer || type == Types.AudioBehaviour #if UNITY_2017_2_OR_NEWER || type == Types.GridLayout #endif ) { continue; } //all GameObjects will always already have a Transform or RectTransform component //and only one can be added to a GameObject, so won't show them in the menu if (type == Types.Transform || type == Types.RectTransform) { continue; } if (Contains(type)) { continue; } //hide obsolete items from the menu if (type.IsDefined(Types.ObsoleteAttribute, false)) { #if DEV_MODE && DEBUG_SKIP_ADDING Debug.LogWarning("Skipping adding " + type.Name + " to Add Component menu because it has the Obsolete attribute"); #endif continue; } Add(type); } itemsByLabel.Clear(); for (int n = rootGroups.Length - 1; n >= 0; n--) { rootGroups[n].GetClassLabelsFlattened(ref pathBuilder, ref itemsByLabel); } if (searchableList != null) { SearchableListPool.Dispose(ref searchableList); } searchableList = SearchableListPool.Create(pathBuilder.ToArray()); pathBuilder.Clear(); #if DEV_MODE AssertHasNoEmptyGroups(rootGroups); #endif // if add component menu config contains any invalid items, remove them RemoveInvalidItems(ref rootGroups); }
public void AddComponent(Type type) { conflictingMembers.Clear(); AddComponentUtility.GetConflictingMembers(type, target, ref conflictingMembers); int conflictCount = conflictingMembers.Count; #if DEV_MODE Debug.Log(GetType().Name + ".AddComponent(" + (type == null ? "null" : type.Name) + ") called with conflictCount=" + conflictCount + "!"); #endif bool viewWasLocked = inspector.State.ViewIsLocked; if (conflictCount == 0) { if (OnComponentAdded != null) { OnComponentAdded(type); } target.AddComponent(type, true); Close(); return; } //more reliable method to get components first? then even if Drawer change, component refs will remain the same //however locking the inspector should do the same thing //var conflictingComponents = conflictingMembers.Select((m)=>m.GetValues()).ToArray(); //TO DO: handle Transform to RectTransform and vice versa //but warn that it requires rebuilding the Components //and could result in lost references? Although I guess //could even try and retain those too, by seraching through //all fields on all objects in hierarchy :D if (type == typeof(Transform)) { Debug.LogError("Replacing Transform Not Yet Supported"); return; } if (type == typeof(RectTransform)) { Debug.LogError("Replacing RectTransform Not Yet Supported"); return; } //TO DO: handle dependencies of all conflicting components too! //so first list conflicting components //then if they have dependencies, list also "which have dependencies with the following components:" string header; string msg; string ok; if (conflictCount == 1) { header = "Conflicting Component"; msg = "Component " + type.Name + " cannot be added because it conflicts with existing Component " + conflictingMembers[0].Type.Name; ok = "Replace Existing"; } else { header = "Conflicting Components"; msg = "Component " + type.Name + " cannot be added because it conflicts with the following exiting Components:" + conflictingMembers[0].Name; foreach (var member in conflictingMembers) { msg += "\n" + member.Type.Name; } ok = "Replace " + conflictCount + " Existing"; } if (DrawGUI.Active.DisplayDialog(header, msg, ok, "Cancel")) { inspector.State.ViewIsLocked = true; foreach (var member in conflictingMembers) { var values = member.GetValues(); for (int n = values.Length - 1; n >= 0; n--) { var comp = values[n] as Component; Platform.Active.Destroy(comp); } } if (OnComponentAdded != null) { OnComponentAdded(type); } target.AddComponent(type, true); inspector.State.ViewIsLocked = viewWasLocked; Close(); } }