static int CompareForOrder(VisualElementAsset a, VisualElementAsset b) => a.orderInDocument.CompareTo(b.orderInDocument);
private VisualElement CloneSetupRecursively(VisualElementAsset root, Dictionary <int, List <VisualElementAsset> > idToChildren, CreationContext context) { VisualElement ve = Create(root, context); if (ve == null) { return(null); } // 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 && TryGetSlotInsertionPoint(root.id, out slotName)) { context.slotInsertionPoints.Add(slotName, ve); } if (root.ruleIndex != -1) { if (inlineSheet == null) { Debug.LogWarning("VisualElementAsset has a RuleIndex but no inlineStyleSheet"); } else { StyleRule r = inlineSheet.rules[root.ruleIndex]; ve.SetInlineRule(inlineSheet, r); } } var templateAsset = root as TemplateAsset; List <VisualElementAsset> children; if (idToChildren.TryGetValue(root.id, out children)) { children.Sort(CompareForOrder); foreach (VisualElementAsset childVea in children) { // this will fill the slotInsertionPoints mapping VisualElement childVe = CloneSetupRecursively(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); }
internal static VisualElement Create(VisualElementAsset asset, CreationContext ctx) { VisualElement CreateError() { Debug.LogErrorFormat("Element '{0}' has no registered factory method.", asset.fullTypeName); return(new Label(string.Format("Unknown type: '{0}'", asset.fullTypeName))); } List <IUxmlFactory> factoryList; if (!VisualElementFactoryRegistry.TryGetValue(asset.fullTypeName, out factoryList)) { if (asset.fullTypeName.StartsWith("UnityEngine.Experimental.UIElements.") || asset.fullTypeName.StartsWith("UnityEditor.Experimental.UIElements.")) { string experimentalTypeName = asset.fullTypeName.Replace(".Experimental.UIElements", ".UIElements"); if (!VisualElementFactoryRegistry.TryGetValue(experimentalTypeName, out factoryList)) { return(CreateError()); } } else if (asset.fullTypeName == "UnityEditor.UIElements.ProgressBar") { string runtimeTypeName = asset.fullTypeName.Replace("UnityEditor", "UnityEngine"); if (!VisualElementFactoryRegistry.TryGetValue(runtimeTypeName, out factoryList)) { return(CreateError()); } } else if (asset.fullTypeName == UxmlRootElementFactory.k_ElementName) { // Support UXML without namespace for backward compatibility. VisualElementFactoryRegistry.TryGetValue(typeof(UxmlRootElementFactory).Namespace + "." + asset.fullTypeName, out factoryList); } else { return(CreateError()); } } IUxmlFactory factory = null; foreach (IUxmlFactory f in factoryList) { if (f.AcceptsAttributeBag(asset, ctx)) { factory = f; break; } } if (factory == null) { Debug.LogErrorFormat("Element '{0}' has a no factory that accept the set of XML attributes specified.", asset.fullTypeName); return(new Label(string.Format("Type with no factory: '{0}'", asset.fullTypeName))); } VisualElement res = factory.Create(asset, ctx); if (res != null) { AssignClassListFromAssetToElement(asset, res); AssignStyleSheetFromAssetToElement(asset, res); } return(res); }
internal void CloneTree(VisualElement target, Dictionary <string, VisualElement> slotInsertionPoints, List <TemplateAsset.AttributeOverride> attributeOverrides) { if (target == null) { throw new ArgumentNullException(nameof(target)); } if ((visualElementAssets == null || visualElementAssets.Count <= 0) && (templateAssets == null || templateAssets.Count <= 0)) { return; } Dictionary <int, List <VisualElementAsset> > idToChildren = new Dictionary <int, List <VisualElementAsset> >(); int eltcount = visualElementAssets == null ? 0 : visualElementAssets.Count; int tplcount = templateAssets == null ? 0 : templateAssets.Count; for (int i = 0; i < eltcount + tplcount; i++) { VisualElementAsset asset = i < eltcount ? visualElementAssets[i] : templateAssets[i - eltcount]; List <VisualElementAsset> children; if (!idToChildren.TryGetValue(asset.parentId, out children)) { children = new List <VisualElementAsset>(); idToChildren.Add(asset.parentId, children); } children.Add(asset); } List <VisualElementAsset> rootAssets; // Tree root have a parentId == 0 idToChildren.TryGetValue(0, out rootAssets); if (rootAssets == null || rootAssets.Count == 0) { return; } Debug.Assert(rootAssets.Count == 1); var root = rootAssets[0]; AssignClassListFromAssetToElement(root, target); AssignStyleSheetFromAssetToElement(root, target); // Get the first-level elements. These will be instantiated and added to target. rootAssets.Clear(); idToChildren.TryGetValue(root.id, out rootAssets); if (rootAssets == null || rootAssets.Count == 0) { return; } rootAssets.Sort(CompareForOrder); foreach (var rootElement in rootAssets) { Assert.IsNotNull(rootElement); VisualElement rootVe = CloneSetupRecursively(rootElement, idToChildren, new CreationContext(slotInsertionPoints, attributeOverrides, this, target)); if (rootVe != null) { // if contentContainer == this, the shadow and the logical hierarchy are identical // otherwise, if there is a CC, we want to insert in the shadow target.hierarchy.Add(rootVe); } else { Debug.LogWarning("VisualTreeAsset instantiated an empty UI. Check the syntax of your UXML document."); } } }
internal static VisualElement Create(VisualElementAsset asset, CreationContext ctx) { List <IUxmlFactory> factoryList; if (!VisualElementFactoryRegistry.TryGetValue(asset.fullTypeName, out factoryList)) { if (asset.fullTypeName.StartsWith("UnityEngine.Experimental.UIElements.") || asset.fullTypeName.StartsWith("UnityEditor.Experimental.UIElements.")) { string experimentalTypeName = asset.fullTypeName.Replace(".Experimental.UIElements", ".UIElements"); if (!VisualElementFactoryRegistry.TryGetValue(experimentalTypeName, out factoryList)) { Debug.LogErrorFormat("Element '{0}' has no registered factory method.", asset.fullTypeName); return(new Label(string.Format("Unknown type: '{0}'", asset.fullTypeName))); } } else { Debug.LogErrorFormat("Element '{0}' has no registered factory method.", asset.fullTypeName); return(new Label(string.Format("Unknown type: '{0}'", asset.fullTypeName))); } } IUxmlFactory factory = null; foreach (IUxmlFactory f in factoryList) { if (f.AcceptsAttributeBag(asset, ctx)) { factory = f; break; } } if (factory == null) { Debug.LogErrorFormat("Element '{0}' has a no factory that accept the set of XML attributes specified.", asset.fullTypeName); return(new Label(string.Format("Type with no factory: '{0}'", asset.fullTypeName))); } if (factory is UxmlRootElementFactory) { return(null); } VisualElement res = factory.Create(asset, ctx); if (res == null) { Debug.LogErrorFormat("The factory of Visual Element Type '{0}' has returned a null object", asset.fullTypeName); return(new Label(string.Format("The factory of Visual Element Type '{0}' has returned a null object", asset.fullTypeName))); } if (asset.classes != null) { for (int i = 0; i < asset.classes.Length; i++) { res.AddToClassList(asset.classes[i]); } } if (asset.stylesheetPaths != null) { for (int i = 0; i < asset.stylesheetPaths.Count; i++) { res.AddStyleSheetPath(asset.stylesheetPaths[i]); } } if (asset.stylesheets != null) { for (int i = 0; i < asset.stylesheets.Count; ++i) { res.styleSheets.Add(asset.stylesheets[i]); } } return(res); }