static void UpdateParentsIncludedState(PrefabOverridesTreeViewItem item) { if (item.depth > 0) { var parent = item.parent as PrefabOverridesTreeViewItem; bool hasIncludedChildren = false; bool hasExcludedChildren = false; foreach (var child in parent.children) { var included = (child as PrefabOverridesTreeViewItem).included; hasIncludedChildren |= included != ToggleValue.FALSE; hasExcludedChildren |= included != ToggleValue.TRUE; if (hasIncludedChildren && hasExcludedChildren) { break; } } if (hasIncludedChildren && hasExcludedChildren) { parent.included = ToggleValue.MIXED; } else if (hasIncludedChildren) { parent.included = ToggleValue.TRUE; } else { parent.included = ToggleValue.FALSE; } UpdateParentsIncludedState(parent); } }
static void UpdateChildrenIncludedState(PrefabOverridesTreeViewItem item, bool v) { item.included = v ? ToggleValue.TRUE : ToggleValue.FALSE; if (item.hasChildren) { foreach (var child in item.children) { UpdateChildrenIncludedState(child as PrefabOverridesTreeViewItem, v); } } }
void DoPreviewPopup(PrefabOverridesTreeViewItem item, Rect rowRect) { if (item != null) { // Ensure preview is shown when clicking on an already selected item (the preview might have been closed) if (Event.current.type == EventType.MouseDown && rowRect.Contains(Event.current.mousePosition) && !PopupWindowWithoutFocus.IsVisible()) { m_ShowPreviewForID = item.id; } // Show preview if (item.id == m_ShowPreviewForID && Event.current.type != EventType.Layout) { m_ShowPreviewForID = -1; if (item.obj != null) { Rect buttonRect = rowRect; buttonRect.width = EditorGUIUtility.currentViewWidth; Object rowObject = item.obj; Object instance, source; if (item.type == ItemType.REMOVED_OBJECT) { instance = null; source = rowObject; } else if (item.type == ItemType.ADDED_OBJECT) { instance = rowObject; source = null; } else { instance = rowObject; source = PrefabUtility.GetCorrespondingObjectFromSource(rowObject); } PopupWindowWithoutFocus.Show( buttonRect, new ComparisonViewPopup(source, instance, item.singleModification, this), new[] { PopupLocation.Right, PopupLocation.Left, PopupLocation.Below }); } } } }
void DoPreviewPopup(PrefabOverridesTreeViewItem item, Rect rowRect) { if (item == null || item.obj == null) { return; } if (PopupWindowWithoutFocus.IsVisible()) { if (item.id == m_LastShownPreviewWindowRowID) { return; } } Rect buttonRect = rowRect; buttonRect.width = EditorGUIUtility.currentViewWidth; Object rowObject = item.obj; Object instance, source; if (item.type == ItemType.REMOVED_OBJECT) { instance = null; source = rowObject; } else if (item.type == ItemType.ADDED_OBJECT) { instance = rowObject; source = null; } else { instance = rowObject; source = PrefabUtility.GetCorrespondingObjectFromSource(rowObject); } m_LastShownPreviewWindowRowID = item.id; PopupWindowWithoutFocus.Show( buttonRect, new ComparisonViewPopup(source, instance, item.singleModification, this), new[] { PopupLocation.Right, PopupLocation.Left, PopupLocation.Below }); }
// Returns true if input gameobject or any of its descendants have modifications, otherwise returns false. bool AddTreeViewItemRecursive(TreeViewItem parentItem, GameObject gameObject, Dictionary <int, PrefabOverrides> prefabOverrideMap, IdSequence idSequence) { var gameObjectItem = new PrefabOverridesTreeViewItem ( gameObject.GetInstanceID(), parentItem.depth + 1, gameObject.name ); gameObjectItem.obj = gameObject; // We don't know yet if this item should be added to the parent. bool shouldAddGameObjectItemToParent = false; PrefabOverrides objectModifications; prefabOverrideMap.TryGetValue(gameObject.GetInstanceID(), out objectModifications); if (objectModifications != null) { // Added GameObject - note that this earlies out! AddedGameObject addedGameObjectData = objectModifications.addedGameObjects.Find(x => x.instanceGameObject == gameObject); if (addedGameObjectData != null) { gameObjectItem.singleModification = addedGameObjectData; gameObjectItem.type = ItemType.ADDED_OBJECT; parentItem.AddChild(gameObjectItem); return(true); } else { // Modified GameObject ObjectOverride modifiedGameObjectData = objectModifications.objectOverrides.Find(x => x.instanceObject == gameObject); if (modifiedGameObjectData != null) { gameObjectItem.singleModification = modifiedGameObjectData; gameObjectItem.type = ItemType.PREFAB_OBJECT; shouldAddGameObjectItemToParent = true; } } // Added components and component modifications foreach (var component in gameObject.GetComponents(typeof(Component))) { // GetComponents will return Missing Script components as null, we will skip them here to prevent NullReferenceExceptions. (case 1197599) if (component == null) { continue; } // Skip coupled components (they are merged into the display of their owning component) if (component.IsCoupledComponent()) { continue; } var componentItem = new PrefabOverridesTreeViewItem ( component.GetInstanceID(), gameObjectItem.depth + 1, ObjectNames.GetInspectorTitle(component) ); componentItem.obj = component; AddedComponent addedComponentData = objectModifications.addedComponents.Find(x => x.instanceComponent == component); if (addedComponentData != null) { // Skip coupled components (they are merged into the display of their owning component) if (addedComponentData.instanceComponent.IsCoupledComponent()) { continue; } componentItem.singleModification = addedComponentData; componentItem.type = ItemType.ADDED_OBJECT; gameObjectItem.AddChild(componentItem); shouldAddGameObjectItemToParent = true; } else { var coupledComponent = component.GetCoupledComponent(); ObjectOverride modifiedObjectData = objectModifications.objectOverrides.Find(x => x.instanceObject == component); ObjectOverride modifiedCoupledObjectData = (coupledComponent != null) ? objectModifications.objectOverrides.Find(x => x.instanceObject == coupledComponent) : null; if (modifiedObjectData != null || modifiedCoupledObjectData != null) { // If only the coupled component has modifications, create an // ObjectOverride object for the main component since it doesn't exist yet. if (modifiedObjectData == null) { modifiedObjectData = new ObjectOverride() { instanceObject = component } } ; modifiedObjectData.coupledOverride = modifiedCoupledObjectData; componentItem.singleModification = modifiedObjectData; componentItem.type = ItemType.PREFAB_OBJECT; gameObjectItem.AddChild(componentItem); shouldAddGameObjectItemToParent = true; } } } // Removed components foreach (var removedComponent in objectModifications.removedComponents) { // Skip coupled components (they are merged into the display of their owning component) if (removedComponent.assetComponent.IsCoupledComponent()) { continue; } var removedComponentItem = new PrefabOverridesTreeViewItem ( idSequence.get(), gameObjectItem.depth + 1, ObjectNames.GetInspectorTitle(removedComponent.assetComponent) ); removedComponentItem.obj = removedComponent.assetComponent; removedComponentItem.singleModification = removedComponent; removedComponentItem.type = ItemType.REMOVED_OBJECT; gameObjectItem.AddChild(removedComponentItem); shouldAddGameObjectItemToParent = true; } } // Recurse into children foreach (Transform childTransform in gameObject.transform) { var childGameObject = childTransform.gameObject; shouldAddGameObjectItemToParent |= AddTreeViewItemRecursive(gameObjectItem, childGameObject, prefabOverrideMap, idSequence); } if (shouldAddGameObjectItemToParent) { parentItem.AddChild(gameObjectItem); if (maxDepthItem == null || gameObjectItem.depth > maxDepthItem.depth) { maxDepthItem = gameObjectItem; } return(true); } return(false); }
// Returns true if input gameobject or any of its descendants have modifications, otherwise returns false. bool AddTreeViewItemRecursive(TreeViewItem parentItem, GameObject gameObject, Dictionary <int, PrefabOverrides> prefabOverrideMap, IdSequence idSequence) { var gameObjectItem = new PrefabOverridesTreeViewItem ( idSequence.get(), parentItem.depth + 1, gameObject.name ); gameObjectItem.obj = gameObject; // We don't know yet if this item should be added to the parent. bool shouldAddGameObjectItemToParent = false; PrefabOverrides objectModifications; prefabOverrideMap.TryGetValue(gameObject.GetInstanceID(), out objectModifications); if (objectModifications != null) { // Added GameObject - note that this earlies out! AddedGameObject addedGameObjectData = objectModifications.addedGameObjects.Find(x => x.instanceGameObject == gameObject); if (addedGameObjectData != null) { gameObjectItem.singleModification = addedGameObjectData; gameObjectItem.type = ItemType.ADDED_OBJECT; parentItem.AddChild(gameObjectItem); return(true); } else { // Modified GameObject ObjectOverride modifiedGameObjectData = objectModifications.objectOverrides.Find(x => x.instanceObject == gameObject); if (modifiedGameObjectData != null) { gameObjectItem.singleModification = modifiedGameObjectData; gameObjectItem.type = ItemType.PREFAB_OBJECT; shouldAddGameObjectItemToParent = true; } } // Added components and component modifications foreach (var component in gameObject.GetComponents(typeof(Component))) { var componentItem = new PrefabOverridesTreeViewItem ( idSequence.get(), gameObjectItem.depth + 1, ObjectNames.GetInspectorTitle(component) ); componentItem.obj = component; AddedComponent addedComponentData = objectModifications.addedComponents.Find(x => x.instanceComponent == component); if (addedComponentData != null) { componentItem.singleModification = addedComponentData; componentItem.type = ItemType.ADDED_OBJECT; gameObjectItem.AddChild(componentItem); shouldAddGameObjectItemToParent = true; } else { ObjectOverride modifiedObjectData = objectModifications.objectOverrides.Find(x => x.instanceObject == component); if (modifiedObjectData != null) { componentItem.singleModification = modifiedObjectData; componentItem.type = ItemType.PREFAB_OBJECT; gameObjectItem.AddChild(componentItem); shouldAddGameObjectItemToParent = true; } } } // Removed components foreach (var removedComponent in objectModifications.removedComponents) { var removedComponentItem = new PrefabOverridesTreeViewItem ( idSequence.get(), gameObjectItem.depth + 1, ObjectNames.GetInspectorTitle(removedComponent.assetComponent) ); removedComponentItem.obj = removedComponent.assetComponent; removedComponentItem.singleModification = removedComponent; removedComponentItem.type = ItemType.REMOVED_OBJECT; gameObjectItem.AddChild(removedComponentItem); shouldAddGameObjectItemToParent = true; } } // Recurse into children foreach (Transform childTransform in gameObject.transform) { var childGameObject = childTransform.gameObject; shouldAddGameObjectItemToParent |= AddTreeViewItemRecursive(gameObjectItem, childGameObject, prefabOverrideMap, idSequence); } if (shouldAddGameObjectItemToParent) { parentItem.AddChild(gameObjectItem); return(true); } return(false); }