コード例 #1
0
 static int CompareForOrder(VisualElementAsset a, VisualElementAsset b) => a.orderInDocument.CompareTo(b.orderInDocument);
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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.");
                }
            }
        }
コード例 #5
0
        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);
        }