public static string GetPathFromTemplateName(this VisualTreeAsset vta, string templateName) { var templateAsset = vta.ResolveTemplate(templateName); if (templateAsset == null) return null; return AssetDatabase.GetAssetPath(templateAsset); }
public static void Swallow(this VisualTreeAsset vta, VisualElementAsset parent, VisualTreeAsset other) { var otherIdToChildren = VisualTreeAssetUtilities.GenerateIdToChildren(other); if (parent == null) { parent = vta.GetRootUXMLElement(); } var nextOrderInDocument = (vta.visualElementAssets.Count + vta.templateAssets.Count) * BuilderConstants.VisualTreeAssetOrderIncrement; var assetsList = new List <VisualElementAsset>(); assetsList.AddRange(other.visualElementAssets); assetsList.AddRange(other.templateAssets); assetsList = assetsList.OrderBy(x => x.orderInDocument).ToList(); foreach (var asset in assetsList) { if (other.IsRootUXMLElement(asset)) { continue; } ReinitElementWithNewParentAsset( vta, parent, other, otherIdToChildren, asset, ref nextOrderInDocument); } foreach (var vea in other.visualElementAssets) { if (other.IsRootUXMLElement(vea)) { continue; } vta.visualElementAssets.Add(vea); } foreach (var vea in other.templateAssets) { if (!vta.TemplateExists(vea.templateAlias)) { vta.RegisterTemplate(vea.templateAlias, other.ResolveTemplate(vea.templateAlias)); } vta.templateAssets.Add(vea); } VisualTreeAssetUtilities.ReOrderDocument(vta); }
static VisualElement CloneSetupRecursively(VisualTreeAsset vta, VisualElementAsset root, Dictionary <int, List <VisualElementAsset> > idToChildren, CreationContext context) { var ve = VisualTreeAsset.Create(root, context); // Linking the new element with its VisualElementAsset. // All this copied code for this one line! ve.SetVisualElementAsset(root); ve.SetProperty(BuilderConstants.ElementLinkedBelongingVisualTreeAssetVEPropertyName, vta); // context.target is the created templateContainer if (root.id == context.visualTreeAsset.contentContainerId) { if (context.target is TemplateContainer) { ((TemplateContainer)context.target).SetContentContainer(ve); } else { Debug.LogError( "Trying to clone a VisualTreeAsset with a custom content container into a element which is not a template container"); } } // if the current element had a slot-name attribute, put it in the resulting slot mapping string slotName; if (context.slotInsertionPoints != null && vta.TryGetSlotInsertionPoint(root.id, out slotName)) { context.slotInsertionPoints.Add(slotName, ve); } if (root.classes != null) { for (int i = 0; i < root.classes.Length; i++) { ve.AddToClassList(root.classes[i]); } } if (root.ruleIndex != -1) { if (vta.inlineSheet == null) { Debug.LogWarning("VisualElementAsset has a RuleIndex but no inlineStyleSheet"); } else { var rule = vta.inlineSheet.rules[root.ruleIndex]; ve.UpdateInlineRule(vta.inlineSheet, rule); } } var templateAsset = root as TemplateAsset; if (templateAsset != null) { var templatePath = vta.GetPathFromTemplateName(templateAsset.templateAlias); ve.SetProperty(BuilderConstants.LibraryItemLinkedTemplateContainerPathVEPropertyName, templatePath); var instancedTemplateVTA = vta.ResolveTemplate(templateAsset.templateAlias); if (instancedTemplateVTA != null) { ve.SetProperty(BuilderConstants.ElementLinkedInstancedVisualTreeAssetVEPropertyName, instancedTemplateVTA); } } List <VisualElementAsset> children; if (idToChildren.TryGetValue(root.id, out children)) { children.Sort(VisualTreeAssetUtilities.CompareForOrder); foreach (VisualElementAsset childVea in children) { if (childVea is UxmlObjectAsset) { continue; } // this will fill the slotInsertionPoints mapping var childVe = CloneSetupRecursively(vta, childVea, idToChildren, context); if (childVe == null) { continue; } // if the parent is not a template asset, just add the child to whatever hierarchy we currently have // if ve is a scrollView (with contentViewport as contentContainer), this will go to the right place if (templateAsset == null) { ve.Add(childVe); continue; } int index = templateAsset.slotUsages == null ? -1 : templateAsset.slotUsages.FindIndex(u => u.assetId == childVea.id); if (index != -1) { VisualElement parentSlot; string key = templateAsset.slotUsages[index].slotName; Assert.IsFalse(String.IsNullOrEmpty(key), "a lost name should not be null or empty, this probably points to an importer or serialization bug"); if (context.slotInsertionPoints == null || !context.slotInsertionPoints.TryGetValue(key, out parentSlot)) { Debug.LogErrorFormat("Slot '{0}' was not found. Existing slots: {1}", key, context.slotInsertionPoints == null ? String.Empty : String.Join(", ", System.Linq.Enumerable.ToArray(context.slotInsertionPoints.Keys))); ve.Add(childVe); } else { parentSlot.Add(childVe); } } else { ve.Add(childVe); } } } if (templateAsset != null && context.slotInsertionPoints != null) { context.slotInsertionPoints.Clear(); } return(ve); }