public static List <string> GetStyleSheetPaths(this VisualElementAsset vea)
 {
     return(vea.stylesheetPaths);
 }
Beispiel #2
0
        private static bool ParseAttributes(XElement elt, VisualElementAsset res, StyleSheetBuilder ssb, VisualTreeAsset vta, VisualElementAsset parent)
        {
            // underscore means "unnamed element but it would not look pretty in the project window without one"
            res.name = "_" + res.GetType().Name;

            bool startedRule = false;

            foreach (XAttribute xattr in elt.Attributes())
            {
                string attrName = xattr.Name.LocalName;

                // start with special cases
                switch (attrName)
                {
                case "name":
                    res.name = xattr.Value;
                    continue;

                case "text":
                    res.text = xattr.Value;
                    continue;

                case "class":
                    res.classes = xattr.Value.Split(' ');
                    continue;

                case "contentContainer":
                    if (vta.contentContainerId != 0)
                    {
                        logger.LogError(ImportErrorType.Semantic, ImportErrorCode.DuplicateContentContainer, null, Error.Level.Fatal, elt);
                        continue;
                    }
                    vta.contentContainerId = res.id;
                    continue;

                case k_SlotDefinitionAttr:
                    if (String.IsNullOrEmpty(xattr.Value))
                    {
                        logger.LogError(ImportErrorType.Semantic, ImportErrorCode.SlotDefinitionHasEmptyName, null, Error.Level.Fatal, elt);
                    }
                    else if (!vta.AddSlotDefinition(xattr.Value, res.id))
                    {
                        logger.LogError(ImportErrorType.Semantic, ImportErrorCode.DuplicateSlotDefinition, xattr.Value, Error.Level.Fatal, elt);
                    }
                    continue;

                case k_SlotUsageAttr:
                    var templateAsset = parent as TemplateAsset;
                    if (!(templateAsset != null))
                    {
                        logger.LogError(ImportErrorType.Semantic, ImportErrorCode.SlotUsageInNonTemplate, parent, Error.Level.Fatal, elt);
                        continue;
                    }
                    if (string.IsNullOrEmpty(xattr.Value))
                    {
                        logger.LogError(ImportErrorType.Semantic, ImportErrorCode.SlotUsageHasEmptyName, null, Error.Level.Fatal, elt);
                        continue;
                    }
                    templateAsset.AddSlotUsage(xattr.Value, res.id);
                    continue;

                case "style":
                    ExCSS.StyleSheet parsed = new Parser().Parse("* { " + xattr.Value + " }");
                    if (parsed.Errors.Count != 0)
                    {
                        logger.LogError(
                            ImportErrorType.Semantic,
                            ImportErrorCode.InvalidCssInStyleAttribute,
                            parsed.Errors.Aggregate("", (s, error) => s + error.ToString() + "\n"),
                            Error.Level.Warning,
                            xattr);
                        continue;
                    }
                    if (parsed.StyleRules.Count != 1)
                    {
                        logger.LogError(
                            ImportErrorType.Semantic,
                            ImportErrorCode.InvalidCssInStyleAttribute,
                            "Expected one style rule, found " + parsed.StyleRules.Count,
                            Error.Level.Warning,
                            xattr);
                        continue;
                    }
                    ssb.BeginRule(-1);
                    startedRule = true;
                    StyleSheetImportErrors errors = new StyleSheetImportErrors();
                    foreach (Property prop in parsed.StyleRules[0].Declarations)
                    {
                        ssb.BeginProperty(prop.Name);
                        StyleSheetImporterImpl.VisitValue(errors, ssb, prop.Term);
                        ssb.EndProperty();
                    }

                    // Don't call ssb.EndRule() here, it's done in LoadXml to get the rule index at the same time !
                    continue;

                case "pickingMode":
                    if (!Enum.IsDefined(typeof(PickingMode), xattr.Value))
                    {
                        Debug.LogErrorFormat("Could not parse value of '{0}', because it isn't defined in the PickingMode enum.", xattr.Value);
                        continue;
                    }
                    res.pickingMode = (PickingMode)Enum.Parse(typeof(PickingMode), xattr.Value);
                    continue;
                }

                res.AddProperty(xattr.Name.LocalName, xattr.Value);
            }
            return(startedRule);
        }
 public static void InitializeElement(VisualElementAsset vea)
 {
     vea.classes         = new string[0];
     vea.orderInDocument = -1;
     vea.ruleIndex       = -1;
 }
Beispiel #4
0
        bool ParseAttributes(XElement elt, VisualElementAsset res, VisualTreeAsset vta, VisualElementAsset parent)
        {
            bool startedRule = false;

            foreach (XAttribute xattr in elt.Attributes())
            {
                string attrName = xattr.Name.LocalName;

                // start with special cases
                switch (attrName)
                {
                case k_ClassAttr:
                    res.AddProperty(xattr.Name.LocalName, xattr.Value);
                    res.classes = xattr.Value.Split(' ');
                    continue;

                case "content-container":
                case "contentContainer":
                    res.AddProperty(xattr.Name.LocalName, xattr.Value);
                    if (attrName == "contentContainer")
                    {
                    }
                    if (vta.contentContainerId != 0)
                    {
                        LogError(vta, ImportErrorType.Semantic, ImportErrorCode.DuplicateContentContainer, null, elt);
                        continue;
                    }
                    vta.contentContainerId = res.id;
                    continue;

                case k_SlotDefinitionAttr:
                    LogWarning(vta, ImportErrorType.Syntax, ImportErrorCode.SlotsAreExperimental, null, elt);
                    if (String.IsNullOrEmpty(xattr.Value))
                    {
                        LogError(vta, ImportErrorType.Semantic, ImportErrorCode.SlotDefinitionHasEmptyName, null, elt);
                    }
                    else if (!vta.AddSlotDefinition(xattr.Value, res.id))
                    {
                        LogError(vta, ImportErrorType.Semantic, ImportErrorCode.DuplicateSlotDefinition, xattr.Value, elt);
                    }
                    continue;

                case k_SlotUsageAttr:
                    LogWarning(vta, ImportErrorType.Syntax, ImportErrorCode.SlotsAreExperimental, null, elt);
                    var templateAsset = parent as TemplateAsset;
                    if (templateAsset == null)
                    {
                        LogError(vta, ImportErrorType.Semantic, ImportErrorCode.SlotUsageInNonTemplate, parent, elt);
                        continue;
                    }
                    if (string.IsNullOrEmpty(xattr.Value))
                    {
                        LogError(vta, ImportErrorType.Semantic, ImportErrorCode.SlotUsageHasEmptyName, null, elt);
                        continue;
                    }
                    templateAsset.AddSlotUsage(xattr.Value, res.id);
                    continue;

                case k_StyleAttr:
                    res.AddProperty(xattr.Name.LocalName, xattr.Value);
                    ExCSS.StyleSheet parsed = new Parser().Parse("* { " + xattr.Value + " }");
                    if (parsed.Errors.Count != 0)
                    {
                        LogWarning(
                            vta,
                            ImportErrorType.Semantic,
                            ImportErrorCode.InvalidCssInStyleAttribute,
                            parsed.Errors.Aggregate("", (s, error) => s + error.ToString() + "\n"),
                            xattr);
                        continue;
                    }
                    if (parsed.StyleRules.Count != 1)
                    {
                        LogWarning(
                            vta,
                            ImportErrorType.Semantic,
                            ImportErrorCode.InvalidCssInStyleAttribute,
                            "Expected one style rule, found " + parsed.StyleRules.Count,
                            xattr);
                        continue;
                    }
                    m_Builder.BeginRule(-1);
                    startedRule   = true;
                    m_CurrentLine = ((IXmlLineInfo)xattr).LineNumber;
                    foreach (Property prop in parsed.StyleRules[0].Declarations)
                    {
                        m_Builder.BeginProperty(prop.Name);
                        VisitValue(prop.Term);
                        m_Builder.EndProperty();
                    }

                    // Don't call m_Builder.EndRule() here, it's done in LoadXml to get the rule index at the same time !
                    continue;
                }

                res.AddProperty(xattr.Name.LocalName, xattr.Value);
            }
            return(startedRule);
        }
Beispiel #5
0
        private static bool ParseAttributes(XElement elt, VisualElementAsset res, StyleSheetBuilder ssb, VisualTreeAsset vta, VisualElementAsset parent)
        {
            res.name = "_" + res.GetType().Name;
            bool result = false;

            foreach (XAttribute current in elt.Attributes())
            {
                string localName = current.Name.LocalName;
                switch (localName)
                {
                case "name":
                    res.name = current.Value;
                    continue;

                case "text":
                    res.text = current.Value;
                    continue;

                case "class":
                    res.classes = current.Value.Split(new char[]
                    {
                        ' '
                    });
                    continue;

                case "contentContainer":
                    if (vta.contentContainerId != 0)
                    {
                        UIElementsViewImporter.logger.LogError(ImportErrorType.Semantic, ImportErrorCode.DuplicateContentContainer, null, UIElementsViewImporter.Error.Level.Fatal, elt);
                        continue;
                    }
                    vta.contentContainerId = res.id;
                    continue;

                case "slot-name":
                    if (string.IsNullOrEmpty(current.Value))
                    {
                        UIElementsViewImporter.logger.LogError(ImportErrorType.Semantic, ImportErrorCode.SlotDefinitionHasEmptyName, null, UIElementsViewImporter.Error.Level.Fatal, elt);
                    }
                    else if (!vta.AddSlotDefinition(current.Value, res.id))
                    {
                        UIElementsViewImporter.logger.LogError(ImportErrorType.Semantic, ImportErrorCode.DuplicateSlotDefinition, current.Value, UIElementsViewImporter.Error.Level.Fatal, elt);
                    }
                    continue;

                case "slot":
                {
                    TemplateAsset templateAsset = parent as TemplateAsset;
                    if (templateAsset == null)
                    {
                        UIElementsViewImporter.logger.LogError(ImportErrorType.Semantic, ImportErrorCode.SlotUsageInNonTemplate, parent, UIElementsViewImporter.Error.Level.Fatal, elt);
                        continue;
                    }
                    if (string.IsNullOrEmpty(current.Value))
                    {
                        UIElementsViewImporter.logger.LogError(ImportErrorType.Semantic, ImportErrorCode.SlotUsageHasEmptyName, null, UIElementsViewImporter.Error.Level.Fatal, elt);
                        continue;
                    }
                    templateAsset.AddSlotUsage(current.Value, res.id);
                    continue;
                }

                case "style":
                {
                    StyleSheet styleSheet = new Parser().Parse("* { " + current.Value + " }");
                    if (styleSheet.Errors.Count != 0)
                    {
                        UIElementsViewImporter.logger.LogError(ImportErrorType.Semantic, ImportErrorCode.InvalidCssInStyleAttribute, styleSheet.Errors.Aggregate("", (string s, StylesheetParseError error) => s + error.ToString() + "\n"), UIElementsViewImporter.Error.Level.Warning, current);
                        continue;
                    }
                    if (styleSheet.StyleRules.Count != 1)
                    {
                        UIElementsViewImporter.logger.LogError(ImportErrorType.Semantic, ImportErrorCode.InvalidCssInStyleAttribute, "Expected one style rule, found " + styleSheet.StyleRules.Count, UIElementsViewImporter.Error.Level.Warning, current);
                        continue;
                    }
                    ssb.BeginRule(-1);
                    result = true;
                    StyleSheetImportErrors errors = new StyleSheetImportErrors();
                    foreach (Property current2 in styleSheet.StyleRules[0].Declarations)
                    {
                        ssb.BeginProperty(current2.Name);
                        StyleSheetImporterImpl.VisitValue(errors, ssb, current2.Term);
                        ssb.EndProperty();
                    }
                    continue;
                }

                case "pickingMode":
                    if (!Enum.IsDefined(typeof(PickingMode), current.Value))
                    {
                        Debug.LogErrorFormat("Could not parse value of '{0}', because it isn't defined in the PickingMode enum.", new object[]
                        {
                            current.Value
                        });
                        continue;
                    }
                    res.pickingMode = (PickingMode)Enum.Parse(typeof(PickingMode), current.Value);
                    continue;
                }
                res.AddProperty(current.Name.LocalName, current.Value);
            }
            return(result);
        }
 static void AppendElementNonStyleAttributes(VisualElementAsset vea, StringBuilder stringBuilder, bool writingToFile)
 {
     AppendElementAttributes(vea, stringBuilder, writingToFile, "class", "style");
 }
        void ImportFactoriesFromSource(LibraryTreeItem sourceCategory)
        {
            List <IUxmlFactory>     deferredFactories = new List <IUxmlFactory>();
            FactoryProcessingHelper processingData    = new FactoryProcessingHelper();

            foreach (var factories in VisualElementFactoryRegistry.factories)
            {
                if (factories.Value.Count == 0)
                {
                    continue;
                }

                var factory = factories.Value[0];
                if (!ProcessFactory(factory, processingData))
                {
                    // Could not process the factory now, because it depends on a yet unprocessed factory.
                    // Defer its processing.
                    deferredFactories.Add(factory);
                }
            }

            List <IUxmlFactory> deferredFactoriesCopy;

            do
            {
                deferredFactoriesCopy = new List <IUxmlFactory>(deferredFactories);
                foreach (var factory in deferredFactoriesCopy)
                {
                    deferredFactories.Remove(factory);
                    if (!ProcessFactory(factory, processingData))
                    {
                        // Could not process the factory now, because it depends on a yet unprocessed factory.
                        // Defer its processing again.
                        deferredFactories.Add(factory);
                    }
                }
            }while (deferredFactoriesCopy.Count > deferredFactories.Count);

            if (deferredFactories.Count > 0)
            {
                Debug.Log("Some factories could not be processed because their base type is missing.");
            }

            var categoryStack = new List <LibraryTreeItem>();

            foreach (var known in processingData.knownTypes.Values)
            {
                var split = known.uxmlNamespace.Split('.');

                // Avoid adding our own internal factories (like Package Manager templates).
                if (!Unsupported.IsDeveloperMode() && split.Count() > 0 && s_NameSpacesToAvoid.Contains(split[0]))
                {
                    continue;
                }

                AddCategoriesToStack(sourceCategory, categoryStack, split);

                var asset = new VisualElementAsset(known.uxmlQualifiedName);

                var slots     = new Dictionary <string, VisualElement>();
                var overrides = new List <TemplateAsset.AttributeOverride>();
                var vta       = ScriptableObject.CreateInstance <VisualTreeAsset>();
                var context   = new CreationContext(slots, overrides, vta, null);

                var newItem = new LibraryTreeItem(
                    known.uxmlName, () => known.Create(asset, context));
                if (categoryStack.Count == 0)
                {
                    sourceCategory.AddChild(newItem);
                }
                else
                {
                    categoryStack.Last().AddChild(newItem);
                }
            }
        }
 public static void Select(this VisualElementAsset vea)
 {
     vea.SetAttributeValue(
         BuilderConstants.SelectedVisualElementAssetAttributeName,
         BuilderConstants.SelectedVisualElementAssetAttributeValue);
 }
 public static void Deselect(this VisualElementAsset vea)
 {
     vea.SetAttributeValue(
         BuilderConstants.SelectedVisualElementAssetAttributeName,
         string.Empty);
 }
        static void GenerateUXMLRecursive(
            VisualTreeAsset vta, string vtaPath, VisualElementAsset root,
            Dictionary <int, List <VisualElementAsset> > idToChildren,
            StringBuilder stringBuilder, int depth,
            bool omitUnsavedUss, bool writingToFile)
        {
            Indent(stringBuilder, depth);

            stringBuilder.Append("<");
            AppendElementTypeName(root, stringBuilder);

            // Add all non-style attributes.
            AppendElementNonStyleAttributes(root, stringBuilder, writingToFile);

            // Add style classes to class attribute.
            if (root.classes != null && root.classes.Length > 0)
            {
                stringBuilder.Append(" class=\"");
                for (int i = 0; i < root.classes.Length; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append(" ");
                    }

                    stringBuilder.Append(root.classes[i]);
                }
                stringBuilder.Append("\"");
            }

            // Add inline StyleSheet attribute.
            if (root.ruleIndex != -1)
            {
                if (vta.inlineSheet == null)
                {
                    Debug.LogWarning("VisualElementAsset has a RuleIndex but no inlineStyleSheet");
                }
                else
                {
                    StyleRule r = vta.inlineSheet.rules[root.ruleIndex];

                    if (r.properties != null && r.properties.Length > 0)
                    {
                        var ruleBuilder   = new StringBuilder();
                        var exportOptions = new UssExportOptions();
                        exportOptions.propertyIndent = string.Empty;
                        StyleSheetToUss.ToUssString(vta.inlineSheet, exportOptions, r, ruleBuilder);
                        var ruleStr = ruleBuilder.ToString();

                        AppendElementAttribute("style", ruleStr, stringBuilder);
                    }
                }
            }

            // If we have no children, avoid adding the full end tag and just end the open tag.
            bool hasChildTags = false;

            // Add special children.
#if UNITY_2019_3_OR_NEWER2
            var styleSheets = root.stylesheets;
            if (styleSheets != null && styleSheets.Count > 0)
            {
                bool newLineAdded = false;

                foreach (var styleSheet in styleSheets)
                {
                    var path = AssetDatabase.GetAssetPath(styleSheet);
                    ProcessStyleSheetPath(
                        vtaPath,
                        path, stringBuilder, depth, omitUnsavedUss,
                        ref newLineAdded, ref hasChildTags);
                }
            }
#else
            var styleSheetPaths = root.GetStyleSheetPaths();
            if (styleSheetPaths != null && styleSheetPaths.Count > 0)
            {
                bool newLineAdded = false;

                foreach (var path in styleSheetPaths)
                {
                    ProcessStyleSheetPath(
                        vtaPath,
                        path, stringBuilder, depth, omitUnsavedUss,
                        ref newLineAdded, ref hasChildTags);
                }
            }
#endif

            var templateAsset = root as TemplateAsset;
            if (templateAsset != null && templateAsset.attributeOverrides != null && templateAsset.attributeOverrides.Count > 0)
            {
                if (!hasChildTags)
                {
                    stringBuilder.Append(">\n");
                }

                var overridesMap = new Dictionary <string, List <TemplateAsset.AttributeOverride> >();
                foreach (var attributeOverride in templateAsset.attributeOverrides)
                {
                    if (!overridesMap.ContainsKey(attributeOverride.m_ElementName))
                    {
                        overridesMap.Add(attributeOverride.m_ElementName, new List <TemplateAsset.AttributeOverride>());
                    }

                    overridesMap[attributeOverride.m_ElementName].Add(attributeOverride);
                }
                foreach (var attributeOverridePair in overridesMap)
                {
                    var elementName = attributeOverridePair.Key;
                    var overrides   = attributeOverridePair.Value;

                    Indent(stringBuilder, depth + 1);
                    stringBuilder.Append("<AttributeOverrides");
                    AppendElementAttribute("element-name", elementName, stringBuilder);

                    foreach (var attributeOverride in overrides)
                    {
                        AppendElementAttribute(attributeOverride.m_AttributeName, attributeOverride.m_Value, stringBuilder);
                    }

                    stringBuilder.Append(" />\n");
                }

                hasChildTags = true;
            }

            // Iterate through child elements.
            List <VisualElementAsset> children;
            if (idToChildren != null && idToChildren.TryGetValue(root.id, out children) && children.Count > 0)
            {
                if (!hasChildTags)
                {
                    stringBuilder.Append(">\n");
                }

                children.Sort(VisualTreeAssetUtilities.CompareForOrder);

                foreach (VisualElementAsset childVea in children)
                {
                    GenerateUXMLRecursive(
                        vta, vtaPath, childVea, idToChildren, stringBuilder,
                        depth + 1, omitUnsavedUss, writingToFile);
                }

                hasChildTags = true;
            }

            if (hasChildTags)
            {
                Indent(stringBuilder, depth);
                stringBuilder.Append("</");
                AppendElementTypeName(root, stringBuilder);
                stringBuilder.Append(">\n");
            }
            else
            {
                stringBuilder.Append(" />\n");
            }
        }
        public static bool IsSelected(this VisualElementAsset vea)
        {
            var value = vea.GetAttributeValue(BuilderConstants.SelectedVisualElementAssetAttributeName);

            return(value == BuilderConstants.SelectedVisualElementAssetAttributeValue);
        }
 public static void RemoveStyleSheetPath(this VisualElementAsset vea, string styleSheetPath)
 {
     vea.GetStyleSheetPaths().RemoveAll((s) => s == styleSheetPath);
 }
 public static void RemoveStyleSheet(this VisualElementAsset vea, StyleSheet styleSheet)
 {
     vea.stylesheets.RemoveAll((s) => s == styleSheet);
 }
 public static void ClearStyleSheets(this VisualElementAsset vea)
 {
     vea.stylesheets.Clear();
     vea.GetStyleSheetPaths().Clear();
 }
Beispiel #15
0
        static List <TreeViewItem> GenerateControlsItemsTree()
        {
            var containersItem = CreateItem(BuilderConstants.LibraryContainersSectionHeaderName, null, null, null, id: 1, isHeader: true);
            var controlsTree   = new List <TreeViewItem>();
            IList <TreeViewItem> containersItemList = new List <TreeViewItem>
            {
                CreateItem("VisualElement", "VisualElement", typeof(VisualElement), () =>
                {
                    var ve              = new VisualElement();
                    var veMinSizeChild  = new VisualElement();
                    veMinSizeChild.name = BuilderConstants.SpecialVisualElementInitialMinSizeName;
                    veMinSizeChild.AddToClassList(BuilderConstants.SpecialVisualElementInitialMinSizeClassName);
                    ve.Add(veMinSizeChild);
                    return(ve);
                },
                           (inVta, inParent, ve) =>
                {
                    var vea = new VisualElementAsset(typeof(VisualElement).ToString());
                    VisualTreeAssetUtilities.InitializeElement(vea);
                    inVta.AddElement(inParent, vea);
                    return(vea);
                }),
                CreateItem("ScrollView", "ScrollView", typeof(ScrollView), () => new ScrollView()),
                CreateItem("ListView", "ListView", typeof(ListView), () => new ListView()),
                CreateItem("GroupBox", "VisualElement", typeof(GroupBox), () => new GroupBox()),
            };

            containersItem.AddChildren(containersItemList);
            controlsTree.Add(containersItem);

            var editorContainersItemList = CreateItem(BuilderConstants.LibraryEditorContainersSectionHeaderName, null, null, null, null, new List <TreeViewItemData <BuilderLibraryTreeItem> >
            {
                CreateItem("IMGUI Container", "VisualElement", typeof(IMGUIContainer), () => new IMGUIContainer()),
            }, id: 2, isEditorOnly: true, isHeader: true);

            var controlsItem = CreateItem(BuilderConstants.LibraryControlsSectionHeaderName, null, null, null, null, new List <TreeViewItemData <BuilderLibraryTreeItem> >
            {
                CreateItem("Label", nameof(Label), typeof(Label), () => new Label("Label")),
                CreateItem("Button", nameof(Button), typeof(Button), () => new Button {
                    text = "Button"
                }),
                CreateItem("Toggle", nameof(Toggle), typeof(Toggle), () => new Toggle("Toggle")),
                CreateItem("Scroller", nameof(Scroller), typeof(Scroller), () => new Scroller(0, 100, (v) => {}, SliderDirection.Horizontal)
                {
                    value = 42
                }),
                CreateItem("Text Field", nameof(TextField), typeof(TextField), () => new TextField("Text Field")
                {
                    value = "filler text"
                }),
                CreateItem("Foldout", nameof(Foldout), typeof(Foldout), () => new Foldout {
                    text = "Foldout"
                }),
                CreateItem("Slider", nameof(Slider), typeof(Slider), () => new Slider("Slider", 0, 100)
                {
                    value = 42
                }),
                CreateItem("Slider (Int)", nameof(SliderInt), typeof(SliderInt), () => new SliderInt("SliderInt", 0, 100)
                {
                    value = 42
                }),
                CreateItem("Min-Max Slider", nameof(MinMaxSlider), typeof(MinMaxSlider), () => new MinMaxSlider("Min/Max Slider", 0, 20, -10, 40)
                {
                    value = new Vector2(10, 12)
                }),
                CreateItem("Progress Bar", nameof(ProgressBar), typeof(ProgressBar), () => new ProgressBar()
                {
                    title = "my-progress", value = 22
                }),
                CreateItem("Dropdown", "Dropdown", typeof(DropdownField), () => new DropdownField("Dropdown")),
                CreateItem("Enum", nameof(EnumField), typeof(EnumField), () => new EnumField("Enum", TextAlignment.Center)),
                CreateItem("Radio Button", nameof(RadioButton), typeof(RadioButton), () => new RadioButton("Radio Button")),
                CreateItem("Radio Button Group", nameof(RadioButtonGroup), typeof(RadioButtonGroup), () => new RadioButtonGroup("Radio Button Group")),
            }, isHeader: true);

            var numericFields = CreateItem("Numeric Fields", null, null, null, null, new List <TreeViewItemData <BuilderLibraryTreeItem> >
            {
                CreateItem("Integer", nameof(IntegerField), typeof(IntegerField), () => new IntegerField("Int Field")
                {
                    value = 42
                }),
                CreateItem("Float", nameof(FloatField), typeof(FloatField), () => new FloatField("Float Field")
                {
                    value = 42.2f
                }),
                CreateItem("Long", nameof(LongField), typeof(LongField), () => new LongField("Long Field")
                {
                    value = 42
                }),
                CreateItem("Double", nameof(DoubleField), typeof(DoubleField), () => new DoubleField("Double Field")
                {
                    value = 42.2
                }),
                CreateItem("Hash128", nameof(Hash128Field), typeof(Hash128Field), () => new Hash128Field("Hash128 Field")
                {
                    value = Hash128.Compute("42")
                }),
                CreateItem("Vector2", nameof(Vector2Field), typeof(Vector2Field), () => new Vector2Field("Vec2 Field")),
                CreateItem("Vector3", nameof(Vector3Field), typeof(Vector3Field), () => new Vector3Field("Vec3 Field")),
                CreateItem("Vector4", nameof(Vector4Field), typeof(Vector4Field), () => new Vector4Field("Vec4 Field")),
                CreateItem("Rect", nameof(RectField), typeof(RectField), () => new RectField("Rect")),
                CreateItem("Bounds", nameof(BoundsField), typeof(BoundsField), () => new BoundsField("Bounds")),
                CreateItem("Vector2 (Int)", nameof(Vector2IntField), typeof(Vector2IntField), () => new Vector2IntField("Vector2Int")),
                CreateItem("Vector3 (Int)", nameof(Vector3IntField), typeof(Vector3IntField), () => new Vector3IntField("Vector3Int")),
                CreateItem("Rect (Int)", nameof(RectIntField), typeof(RectIntField), () => new RectIntField("RectInt")),
                CreateItem("Bounds (Int)", nameof(BoundsIntField), typeof(BoundsIntField), () => new BoundsIntField("BoundsInt")),
            }, isHeader: true);

            var valueFields = CreateItem("Value Fields", null, null, null, null, new List <TreeViewItemData <BuilderLibraryTreeItem> >
            {
                CreateItem("Color", nameof(ColorField), typeof(ColorField), () => new ColorField("Color")
                {
                    value = Color.cyan
                }),
                CreateItem("Curve", nameof(CurveField), typeof(CurveField), () => new CurveField("Curve")
                {
                    value = new AnimationCurve(new Keyframe(0, 0), new Keyframe(5, 8), new Keyframe(10, 4))
                }),
                CreateItem("Gradient", nameof(GradientField), typeof(GradientField), () => new GradientField("Gradient")
                {
                    value = new Gradient()
                    {
                        colorKeys = new[]
                        {
                            new GradientColorKey(Color.red, 0),
                            new GradientColorKey(Color.blue, 10),
                            new GradientColorKey(Color.green, 20)
                        }
                    }
                })
            }, isEditorOnly: true, isHeader: true);

            var choiceFields = CreateItem("Choice Fields", null, null, null, null, new List <TreeViewItemData <BuilderLibraryTreeItem> >
            {
                // No UXML support for PopupField.
                //new LibraryTreeItem("Popup", () => new PopupField<string>("Normal Field", choices, 0)),

                CreateItem("Tag", nameof(TagField), typeof(TagField), () => new TagField("Tag", "Player")),
                CreateItem("Mask", nameof(MaskField), typeof(MaskField), () => new MaskField("Mask")),
                CreateItem("Layer", nameof(LayerField), typeof(LayerField), () => new LayerField("Layer")),
                CreateItem("LayerMask", nameof(LayerMaskField), typeof(LayerMaskField), () => new LayerMaskField("LayerMask"))
            }, isEditorOnly: true, isHeader: true);

            var toolbar = CreateItem("Toolbar", null, null, null, null, new List <TreeViewItemData <BuilderLibraryTreeItem> >
            {
                CreateItem("Toolbar", "ToolbarElement", typeof(Toolbar), () => new Toolbar()),
                CreateItem("Toolbar Menu", "ToolbarElement", typeof(ToolbarMenu), () => new ToolbarMenu()),
                CreateItem("Toolbar Button", "ToolbarElement", typeof(ToolbarButton), () => new ToolbarButton {
                    text = "Button"
                }),
                CreateItem("Toolbar Spacer", "ToolbarElement", typeof(ToolbarSpacer), () => new ToolbarSpacer()),
                CreateItem("Toolbar Toggle", "ToolbarElement", typeof(ToolbarToggle), () => new ToolbarToggle {
                    label = "Toggle"
                }),
                CreateItem("Toolbar Breadcrumbs", "ToolbarElement", typeof(ToolbarBreadcrumbs), () => new ToolbarBreadcrumbs()),
                CreateItem("Toolbar Search Field", "ToolbarElement", typeof(ToolbarSearchField), () => new ToolbarSearchField()),
                CreateItem("Toolbar Popup Search Field", "ToolbarElement", typeof(ToolbarPopupSearchField), () => new ToolbarPopupSearchField()),
            }, isEditorOnly: true, isHeader: true);

            var inspectors = CreateItem("Inspectors", null, null, null, null, new List <TreeViewItemData <BuilderLibraryTreeItem> >
            {
                CreateItem("Object Field", nameof(ObjectField), typeof(ObjectField), () => new ObjectField("Object Field")
                {
                    value = new Texture2D(10, 10)
                    {
                        name = "new_texture"
                    }
                }),
                CreateItem("PropertyField", nameof(PropertyField), typeof(PropertyField), () => new PropertyField())
            }, isEditorOnly: true, isHeader: true);

            controlsTree.Add(editorContainersItemList);
            controlsTree.Add(controlsItem);
            controlsTree.Add(numericFields);
            controlsTree.Add(valueFields);
            controlsTree.Add(choiceFields);
            controlsTree.Add(toolbar);
            controlsTree.Add(inspectors);

            return(controlsTree);
        }
 public static bool HasParent(this VisualElementAsset vea)
 {
     return(vea.parentId != 0);
 }
        static void GenerateUXMLRecursive(
            VisualTreeAsset vta, string vtaPath, VisualElementAsset root,
            Dictionary <int, List <VisualElementAsset> > idToChildren,
            StringBuilder stringBuilder, int depth, bool writingToFile)
        {
            Indent(stringBuilder, depth);

            stringBuilder.Append(BuilderConstants.UxmlOpenTagSymbol);
            AppendElementTypeName(root, stringBuilder);

            // Add all non-style attributes.
            AppendElementNonStyleAttributes(root, stringBuilder, writingToFile);

            // Add style classes to class attribute.
            if (root.classes != null && root.classes.Length > 0)
            {
                stringBuilder.Append(" class=\"");
                for (int i = 0; i < root.classes.Length; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append(" ");
                    }

                    stringBuilder.Append(root.classes[i]);
                }
                stringBuilder.Append("\"");
            }

            // Add inline StyleSheet attribute.
            if (root.ruleIndex != -1)
            {
                if (vta.inlineSheet == null)
                {
                    Debug.LogWarning("VisualElementAsset has a RuleIndex but no inlineStyleSheet");
                }
                else
                {
                    StyleRule r = vta.inlineSheet.rules[root.ruleIndex];

                    if (r.properties != null && r.properties.Length > 0)
                    {
                        var ruleBuilder   = new StringBuilder();
                        var exportOptions = new UssExportOptions();
                        exportOptions.propertyIndent = string.Empty;
                        StyleSheetToUss.ToUssString(vta.inlineSheet, exportOptions, r, ruleBuilder);
                        var ruleStr = ruleBuilder.ToString();

                        // Need to remove newlines here before we give it to
                        // AppendElementAttribute() so we don't add "&#10;" everywhere.
                        ruleStr = ruleStr.Replace("\n", " ");
                        ruleStr = ruleStr.Replace("\r", "");
                        ruleStr = ruleStr.Trim();

                        AppendElementAttribute("style", ruleStr, stringBuilder);
                    }
                }
            }

            // If we have no children, avoid adding the full end tag and just end the open tag.
            bool hasChildTags = false;

            // Add special children.
            var styleSheets     = root.GetStyleSheets();
            var styleSheetPaths = root.GetStyleSheetPaths();

            if (styleSheetPaths != null && styleSheetPaths.Count > 0)
            {
                Assert.IsNotNull(styleSheets);
                Assert.AreEqual(styleSheetPaths.Count, styleSheets.Count);

                bool newLineAdded = false;

                for (var i = 0; i < styleSheetPaths.Count; ++i)
                {
                    var styleSheet     = styleSheets[i];
                    var styleSheetPath = styleSheetPaths[i];
                    ProcessStyleSheetPath(
                        vtaPath,
                        styleSheet, styleSheetPath, stringBuilder, depth,
                        ref newLineAdded, ref hasChildTags);
                }
            }

            var templateAsset = root as TemplateAsset;

            if (templateAsset != null && templateAsset.attributeOverrides != null && templateAsset.attributeOverrides.Count > 0)
            {
                if (!hasChildTags)
                {
                    stringBuilder.Append(BuilderConstants.UxmlCloseTagSymbol);
                    stringBuilder.Append(BuilderConstants.newlineCharFromEditorSettings);
                }

                var overridesMap = new Dictionary <string, List <TemplateAsset.AttributeOverride> >();
                foreach (var attributeOverride in templateAsset.attributeOverrides)
                {
                    if (!overridesMap.ContainsKey(attributeOverride.m_ElementName))
                    {
                        overridesMap.Add(attributeOverride.m_ElementName, new List <TemplateAsset.AttributeOverride>());
                    }

                    overridesMap[attributeOverride.m_ElementName].Add(attributeOverride);
                }
                foreach (var attributeOverridePair in overridesMap)
                {
                    var elementName = attributeOverridePair.Key;
                    var overrides   = attributeOverridePair.Value;

                    Indent(stringBuilder, depth + 1);
                    stringBuilder.Append(BuilderConstants.UxmlOpenTagSymbol + "AttributeOverrides");
                    AppendElementAttribute("element-name", elementName, stringBuilder);

                    foreach (var attributeOverride in overrides)
                    {
                        AppendElementAttribute(attributeOverride.m_AttributeName, attributeOverride.m_Value, stringBuilder);
                    }

                    stringBuilder.Append(" " + BuilderConstants.UxmlCloseTagSymbol);
                    stringBuilder.Append(BuilderConstants.newlineCharFromEditorSettings);
                }

                hasChildTags = true;
            }

            // Iterate through child elements.
            List <VisualElementAsset> children;

            if (idToChildren != null && idToChildren.TryGetValue(root.id, out children) && children.Count > 0)
            {
                if (!hasChildTags)
                {
                    stringBuilder.Append(BuilderConstants.UxmlCloseTagSymbol);
                    stringBuilder.Append(BuilderConstants.newlineCharFromEditorSettings);
                }

                children.Sort(VisualTreeAssetUtilities.CompareForOrder);

                foreach (var childVea in children)
                {
                    GenerateUXMLRecursive(
                        vta, vtaPath, childVea, idToChildren, stringBuilder,
                        depth + 1, writingToFile);
                }

                hasChildTags = true;
            }

            // Iterate through Uxml Objects
            var entry = vta.GetUxmlObjectEntry(root.id);

            if (entry.uxmlObjectAssets != null && entry.uxmlObjectAssets.Count > 0)
            {
                if (!hasChildTags)
                {
                    stringBuilder.Append(BuilderConstants.UxmlCloseTagSymbol);
                    stringBuilder.Append(BuilderConstants.newlineCharFromEditorSettings);
                }

                foreach (var childVea in entry.uxmlObjectAssets)
                {
                    GenerateUXMLRecursive(
                        vta, vtaPath, childVea, idToChildren, stringBuilder,
                        depth + 1, writingToFile);
                }

                hasChildTags = true;
            }

            if (hasChildTags)
            {
                Indent(stringBuilder, depth);
                stringBuilder.Append(BuilderConstants.UxmlOpenTagSymbol + "/");
                AppendElementTypeName(root, stringBuilder);
                stringBuilder.Append(BuilderConstants.UxmlCloseTagSymbol);
                stringBuilder.Append(BuilderConstants.newlineCharFromEditorSettings);
            }
            else
            {
                stringBuilder.Append(" " + BuilderConstants.UxmlEndTagSymbol);
                stringBuilder.Append(BuilderConstants.newlineCharFromEditorSettings);
            }
        }
 public static void SetAttributeValue(this VisualElementAsset vea, string attributeName, string attributeValue)
 {
     vea.AddProperty(attributeName, attributeValue);
 }
 public static void SetVisualElementAsset(this VisualElement element, VisualElementAsset vea)
 {
     element.SetProperty(BuilderConstants.ElementLinkedVisualElementAssetVEPropertyName, vea);
 }
        static VisualElement CloneSetupRecursively(VisualTreeAsset vta, VisualElementAsset root,
                                                   Dictionary <int, List <VisualElementAsset> > idToChildren, CreationContext context)
        {
#if UNITY_2019_3_OR_NEWER
            var resolvedSheets = new List <StyleSheet>();
            foreach (var sheetPath in root.stylesheetPaths)
            {
                resolvedSheets.Add(AssetDatabase.LoadAssetAtPath <StyleSheet>(sheetPath));
            }
            root.stylesheets = resolvedSheets;
#endif

            var ve = VisualTreeAsset.Create(root, context);

            // Linking the new element with its VisualElementAsset.
            // All this copied code for this one line!
            ve.SetProperty(BuilderConstants.ElementLinkedVisualElementAssetVEPropertyName, root);

            // 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];
#if UNITY_2020_1_OR_NEWER
                    ve.SetInlineRule(vta.inlineSheet, rule);
#elif UNITY_2019_3_OR_NEWER
                    var stylesData = new VisualElementStylesData(false);
                    ve.SetInlineStyles(stylesData);
                    s_StylePropertyReader.SetInlineContext(vta.inlineSheet, rule, root.ruleIndex);
                    stylesData.ApplyProperties(s_StylePropertyReader, null);
#else
                    var stylesData = new VisualElementStylesData(false);
                    ve.SetInlineStyles(stylesData);
                    var propIds = StyleSheetCache.GetPropertyIDs(vta.inlineSheet, root.ruleIndex);
                    stylesData.ApplyRule(vta.inlineSheet, Int32.MaxValue, rule, propIds);
#endif
                }
            }

            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)
                {
                    // this will fill the slotInsertionPoints mapping
                    VisualElement 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);
        }
        void RefreshTreeView()
        {
            Clear();

            var choices = new List <string> {
                "First", "Second", "Third"
            };

            LibraryTreeItem.ResetNextId();
            var items = new List <ITreeViewItem>();

            var unityItem = new LibraryTreeItem("Unity", () => null);

            unityItem.isHeader = true;
            IList <ITreeViewItem> unityItemList = new List <ITreeViewItem>()
            {
                new LibraryTreeItem("VisualElement",
                                    () =>
                {
                    var ve              = new VisualElement();
                    var veMinSizeChild  = new VisualElement();
                    veMinSizeChild.name = BuilderConstants.SpecialVisualElementInitialMinSizeName;
                    veMinSizeChild.AddToClassList(BuilderConstants.SpecialVisualElementInitialMinSizeClassName);
                    ve.Add(veMinSizeChild);
                    return(ve);
                },
                                    (inVta, inParent) =>
                {
                    var vea = new VisualElementAsset(typeof(VisualElement).ToString());
                    VisualTreeAssetUtilities.InitializeElement(vea);
                    inVta.AddElement(inParent, vea);
                    return(vea);
                }),
                new LibraryTreeItem("Button", () => new Button()
                {
                    text = "Button"
                }),
                new LibraryTreeItem("Scroller", () => new Scroller(0, 100, (v) => { }, SliderDirection.Horizontal)
                {
                    value = 42
                }),
                new LibraryTreeItem("Toggle", () => new Toggle("Toggle")),
                new LibraryTreeItem("Label", () => new Label("Label")),
                new LibraryTreeItem("Text Field", () => new TextField("Text Field")
                {
                    value = "filler text"
                }),
                new LibraryTreeItem("Object Field", () => new ObjectField("Object Field")
                {
                    value = new Texture2D(10, 10)
                    {
                        name = "new_texture"
                    }
                }),
                new LibraryTreeItem("Foldout", () => new Foldout()
                {
                    text = "Foldout"
                }),
                new LibraryTreeItem("Numeric Fields", () => null, null, new List <TreeViewItem <string> >()
                {
                    new LibraryTreeItem("Integer", () => new IntegerField("Int Field")
                    {
                        value = 42
                    }),
                    new LibraryTreeItem("Float", () => new FloatField("Float Field")
                    {
                        value = 42.2f
                    }),
                    new LibraryTreeItem("Long", () => new LongField("Long Field")
                    {
                        value = 42
                    }),
                    new LibraryTreeItem("Min-Max Slider", () => new MinMaxSlider("Min/Max Slider", 0, 20, -10, 40)
                    {
                        value = new Vector2(10, 12)
                    }),
                    new LibraryTreeItem("Slider", () => new Slider("SliderInt", 0, 100)
                    {
                        value = 42
                    }),
                    new LibraryTreeItem("Progress Bar", () => new ProgressBar()
                    {
                        title = "my-progress", value = 22
                    }),
                    new LibraryTreeItem("Vector2", () => new Vector2Field("Vec2 Field")),
                    new LibraryTreeItem("Vector3", () => new Vector3Field("Vec3 Field")),
                    new LibraryTreeItem("Vector4", () => new Vector4Field("Vec4 Field")),
                    new LibraryTreeItem("Rect", () => new RectField("Rect")),
                    new LibraryTreeItem("Bounds", () => new BoundsField("Bounds")),
                    new LibraryTreeItem("Slider (Int)", () => new SliderInt("SliderInt", 0, 100)
                    {
                        value = 42
                    }),
                    new LibraryTreeItem("Vector2 (Int)", () => new Vector2IntField("Vector2Int")),
                    new LibraryTreeItem("Vector3 (Int)", () => new Vector3IntField("Vector3Int")),
                    new LibraryTreeItem("Rect (Int)", () => new RectIntField("RectInt")),
                    new LibraryTreeItem("Bounds (Int)", () => new BoundsIntField("BoundsInt"))
                }),
                new LibraryTreeItem("Value Fields", () => null, null, new List <TreeViewItem <string> >()
                {
                    new LibraryTreeItem("Color", () => new ColorField("Color")
                    {
                        value = Color.cyan
                    }),
                    new LibraryTreeItem("Curve", () => new CurveField("Curve")),
                    new LibraryTreeItem("Gradient", () => new GradientField("Gradient"))
                }),
                new LibraryTreeItem("Choice Fields", () => null, null, new List <TreeViewItem <string> >()
                {
                    new LibraryTreeItem("Enum", () => new EnumField("Enum", TextAlignment.Center)),

                    // No UXML support for PopupField.
                    //new LibraryTreeItem("Popup", () => new PopupField<string>("Normal Field", choices, 0)),

                    new LibraryTreeItem("Tag", () => new TagField("Tag", "Player")),
                    new LibraryTreeItem("Mask", () => new MaskField("Mask")),
                    new LibraryTreeItem("Layer", () => new LayerField("Layer")),
                    new LibraryTreeItem("LayerMask", () => new LayerMaskField("LayerMask"))
                }),
                new LibraryTreeItem("Containers", () => null, null, new List <TreeViewItem <string> >()
                {
                    new LibraryTreeItem("ScrollView", () => new ScrollView()),
                    new LibraryTreeItem("ListView", () => new ListView())
                }),
                new LibraryTreeItem("Inspectors", () => null, null, new List <TreeViewItem <string> >()
                {
                    new LibraryTreeItem("PropertyField", () => new PropertyField())
                }),
            };

            unityItem.AddChildren(unityItemList);
            items.Add(unityItem);

            // From Project
            var fromProjectCategory = new LibraryTreeItem("Project", () => null);

            fromProjectCategory.isHeader = true;
            items.Add(fromProjectCategory);
            ImportUxmlFromProject(fromProjectCategory);
            ImportFactoriesFromSource(fromProjectCategory);

            var treeView = new TreeView()
            {
                name = k_TreeViewName
            };

            treeView.AddToClassList(k_TreeViewClassName);
            Add(treeView);

            treeView.viewDataKey = "samples-tree";
            treeView.itemHeight  = 20;
            treeView.rootItems   = items;
            treeView.makeItem    = () => MakeItem(); // This is apparently more optimal than "= MakeItem;".
            treeView.bindItem    = (e, i) => BindItem(e, i);
#if UNITY_2020_1_OR_NEWER
            treeView.onItemsChosen += (s) => OnItemsChosen(s);
#else
            treeView.onItemChosen += (s) => OnItemChosen(s);
#endif
            treeView.Refresh();

            // Make sure the Hierarchy View gets focus when the pane gets focused.
            primaryFocusable = treeView.Q <ListView>();

            // Auto-expand all items on load.
            foreach (var item in treeView.rootItems)
            {
                treeView.ExpandItem(item.id);
            }
        }
 public static bool IsRootElement(this VisualTreeAsset vta, VisualElementAsset vea)
 {
     return(vea.parentId == vta.GetRootUXMLElementId());
 }
Beispiel #23
0
 private static bool ResolveType(XElement elt, VisualTreeAsset visualTreeAsset, out VisualElementAsset vea)
 {
     if (visualTreeAsset.AliasExists(elt.Name.LocalName))
     {
         vea = new TemplateAsset(elt.Name.LocalName);
     }
     else
     {
         string text = (!string.IsNullOrEmpty(elt.Name.NamespaceName)) ? (elt.Name.NamespaceName + "." + elt.Name.LocalName) : elt.Name.LocalName;
         if (text == typeof(VisualElement).FullName)
         {
             text = typeof(VisualContainer).FullName;
         }
         vea = new VisualElementAsset(text);
     }
     return(true);
 }
 internal static VisualElementAsset AddElement(
     this VisualTreeAsset vta, VisualElementAsset parent, VisualElementAsset vea)
 {
     return(VisualTreeAssetUtilities.AddElementToDocument(vta, vea, parent));
 }
Beispiel #25
0
        private static bool ResolveType(XElement elt, VisualTreeAsset visualTreeAsset, out VisualElementAsset vea)
        {
            string fullName;

            if (visualTreeAsset.AliasExists(elt.Name.LocalName))
            {
                vea = new TemplateAsset(elt.Name.LocalName);
            }
            else
            {
                fullName = String.IsNullOrEmpty(elt.Name.NamespaceName)
                    ? elt.Name.LocalName
                    : elt.Name.NamespaceName + "." + elt.Name.LocalName;

                // HACK: wait for Theo's PR OR go with that
                if (fullName == typeof(VisualElement).FullName)
                {
                    fullName = typeof(VisualContainer).FullName;
                }
                vea = new VisualElementAsset(fullName);
            }

            return(true);
        }
        public static StyleRule GetOrCreateInlineStyleRule(this VisualTreeAsset vta, VisualElementAsset vea)
        {
            bool wasCreated;

            return(vta.GetOrCreateInlineStyleRule(vea, out wasCreated));
        }
 public static int CompareForOrder(VisualElementAsset a, VisualElementAsset b) => a.orderInDocument.CompareTo(b.orderInDocument);
        public void ImportFactoriesFromSource(BuilderLibraryTreeItem sourceCategory)
        {
            var deferredFactories      = new List <IUxmlFactory>();
            var processingData         = new FactoryProcessingHelper();
            var emptyNamespaceControls = new List <ITreeViewItem>();

            foreach (var factories in VisualElementFactoryRegistry.factories)
            {
                if (factories.Value.Count == 0)
                {
                    continue;
                }

                var factory = factories.Value[0];
                if (!ProcessFactory(factory, processingData))
                {
                    // Could not process the factory now, because it depends on a yet unprocessed factory.
                    // Defer its processing.
                    deferredFactories.Add(factory);
                }
            }

            List <IUxmlFactory> deferredFactoriesCopy;

            do
            {
                deferredFactoriesCopy = new List <IUxmlFactory>(deferredFactories);
                foreach (var factory in deferredFactoriesCopy)
                {
                    deferredFactories.Remove(factory);
                    if (!ProcessFactory(factory, processingData))
                    {
                        // Could not process the factory now, because it depends on a yet unprocessed factory.
                        // Defer its processing again.
                        deferredFactories.Add(factory);
                    }
                }
            }while (deferredFactoriesCopy.Count > deferredFactories.Count);

            if (deferredFactories.Count > 0)
            {
                Debug.Log("Some factories could not be processed because their base type is missing.");
            }

            var categoryStack = new List <BuilderLibraryTreeItem>();

            foreach (var known in processingData.knownTypes.Values)
            {
                var split = known.uxmlNamespace.Split('.');
                if (split.Length == 0)
                {
                    continue;
                }

                // Avoid adding our own internal factories (like Package Manager templates).
                if (!Unsupported.IsDeveloperMode() && split.Length > 0 && s_NameSpacesToAvoid.Contains(split[0]))
                {
                    continue;
                }

                // Avoid adding UI Builder's own types, even in internal mode.
                if (split.Length >= 3 && split[0] == "Unity" && split[1] == "UI" && split[2] == "Builder")
                {
                    continue;
                }

                var asset     = new VisualElementAsset(known.uxmlQualifiedName);
                var slots     = new Dictionary <string, VisualElement>();
                var overrides = new List <TemplateAsset.AttributeOverride>();
                var vta       = ScriptableObject.CreateInstance <VisualTreeAsset>();
                var context   = new CreationContext(slots, overrides, vta, null);

                Type elementType = null;
                var  factoryType = known.GetType();
                while (factoryType != null && elementType == null)
                {
                    if (factoryType.IsGenericType && factoryType.GetGenericTypeDefinition() == typeof(UxmlFactory <,>))
                    {
                        elementType = factoryType.GetGenericArguments()[0];
                    }
                    else
                    {
                        factoryType = factoryType.BaseType;
                    }
                }

                var newItem = new BuilderLibraryTreeItem(
                    known.uxmlName, "CustomCSharpElement", elementType, () => known.Create(asset, context));
                newItem.hasPreview = true;

                if (string.IsNullOrEmpty(split[0]))
                {
                    emptyNamespaceControls.Add(newItem);
                }
                else
                {
                    AddCategoriesToStack(sourceCategory, categoryStack, split);
                    if (categoryStack.Count == 0)
                    {
                        sourceCategory.AddChild(newItem);
                    }
                    else
                    {
                        categoryStack.Last().AddChild(newItem);
                    }
                }
            }

            sourceCategory.AddChildren(emptyNamespaceControls);
        }
Beispiel #29
0
        void LoadXml(XElement elt, VisualElementAsset parent, VisualTreeAsset vta, int orderInDocument)
        {
            VisualElementAsset vea = ResolveType(elt, vta);

            if (vea == null)
            {
                return;
            }

            int parentHash;

            if (parent == null)
            {
                vea.parentId = 0;
                parentHash   = vta.GetHashCode();
            }
            else
            {
                vea.parentId = parent.id;
                parentHash   = parent.id;
            }

            // id includes the parent id, meaning it's dependent on the whole direct hierarchy
            vea.id = (vta.GetNextChildSerialNumber() + 585386304) * -1521134295 + parentHash;
            vea.orderInDocument = orderInDocument;

            bool startedRule = ParseAttributes(elt, vea, vta, parent);

            // each vea will creates 0 or 1 style rule, with one or more properties
            // they don't have selectors and are directly referenced by index
            // it's then applied during tree cloning
            vea.ruleIndex = startedRule ? m_Builder.EndRule() : -1;
            var templateAsset = vea as TemplateAsset;

            if (templateAsset != null)
            {
                vta.templateAssets.Add(templateAsset);
            }
            else
            {
                vta.visualElementAssets.Add(vea);
            }

            if (elt.HasElements)
            {
                foreach (XElement child in elt.Elements())
                {
                    if (child.Name.LocalName == k_StyleReferenceNode)
                    {
                        LoadStyleReferenceNode(vea, child);
                    }
                    else if (templateAsset != null && child.Name.LocalName == k_AttributeOverridesNode)
                    {
                        LoadAttributeOverridesNode(templateAsset, child);
                    }
                    else
                    {
                        ++orderInDocument;
                        LoadXml(child, vea, vta, orderInDocument);
                    }
                }
            }
        }
 static void AppendElementNonStyleAttributes(VisualElementAsset vea, StringBuilder stringBuilder, bool writingToFile)
 {
     // In 2019.3, je pense, "class" and "style" are now regular attributes??
     AppendElementAttributes(vea, stringBuilder, writingToFile, "class", "style");
 }