public static VisualElement CreateVisualElement(XmlNode node)
        {
            if (node == null)
            {
                throw new Exception("Node is null");
            }

            // Debug.Log($"Looking for type: {node.Name.Replace("ui:", "")}");
            Type elementType = Array.Find(typeof(VisualElement).Assembly.GetTypes(), x =>
                                          x.Name.Equals(node.Name.Replace("ui:", "")));

            if (elementType == null)
            {
                if (!node.Name.Replace("ui:", "").Equals("Style"))
                {
                    Debug.Log($"Couldn't find type \"{node.Name.Replace("ui:", "")}\"\nSkipping...");
                }

                return(null);
            }

            VisualElement element = (VisualElement)typeof(VisualElement).GetMethod("CreateUnityType")
                                    ?.MakeGenericMethod(elementType)
                                    .Invoke(null, new object[] { new object[] { } });

            // Debug.Log("Creating element..");

            if (node.Attributes != null)
            {
                foreach (XmlAttribute attr in node.Attributes)
                {
                    // Debug.Log("Parsing Attribute");

                    var property = elementType.GetProperty(MapCssName(attr.Name));

                    if (attr.Name.Equals("class"))
                    {
                        //Debug.Log("Class found with value: " + attr.Value);
                        element?.AddToClassList(attr.Value);
                    }

                    if (property == null)
                    {
                        if (!attr.Name.Equals("class"))
                        {
                            Debug.Log($"Skipping attribute \"{attr.Name}\"");
                        }

                        // throw new Exception($"No property found with name \"{attr.Name}\"");
                        continue;
                    }

                    if (property.PropertyType.IsEnum)
                    {
                        property.SetValue(element, Enum.Parse(property.PropertyType, attr.Value));
                        continue;
                    }

                    switch (property.PropertyType.Name)
                    {
                    case "Boolean":
                        // Debug.Log($"Parsing Boolean: {attr.Value}");
                        property.SetValue(element, bool.Parse(attr.Value));
                        break;

                    case "String":
                        // Debug.Log($"Parsing String: {attr.Value}");
                        property.SetValue(element, attr.Value);
                        break;

                    case "IStyle":
                        // Debug.Log("Parsing IStyle");
                        element = ParseStyle(attr.Value, element);
                        break;

                    default:
                        throw new Exception($"Found no matching type to {property.PropertyType.FullName}");
                    }
                }
            }


            VisualElement resultElement = element;

            foreach (XmlNode child in node.ChildNodes)
            {
                var parsedChild = CreateVisualElement(child);
            }

            return(resultElement);
        }
예제 #2
0
 public RecycledItem(VisualElement element)
 {
     this.element = element;
     index        = id = -1;
     element.AddToClassList(itemUssClassName);
 }
예제 #3
0
        public static void BuildInspectorPropertiesElement(string elementPath, IEditorContainer editor, System.Collections.Generic.HashSet <System.Type> usedComponents, SerializedProperty obj, UnityEngine.UIElements.VisualElement container, bool noFields, System.Action <int, PropertyField> onBuild = null)
        {
            obj = obj.Copy();
            container.Clear();
            var source = obj.Copy();
            SerializedProperty iterator = obj;

            if (iterator.NextVisible(true) == false)
            {
                return;
            }
            if (iterator.NextVisible(true) == false)
            {
                return;
            }
            var depth        = iterator.depth;
            var i            = 0;
            var iteratorNext = iterator.Copy();

            do
            {
                if (string.IsNullOrEmpty(elementPath) == false)
                {
                    iterator = iteratorNext.FindPropertyRelative(elementPath);
                }
                else
                {
                    iterator = iteratorNext;
                }
                if (iterator.propertyType != SerializedPropertyType.ManagedReference)
                {
                    continue;
                }

                var element = new VisualElement();
                element.AddToClassList("element");

                var itCopy = iterator.Copy();
                GetTypeFromManagedReferenceFullTypeName(iterator.managedReferenceFullTypename, out var type);
                element.AddToClassList(i % 2 == 0 ? "even" : "odd");
                element.RegisterCallback <UnityEngine.UIElements.ContextClickEvent, int>((evt, idx) => {
                    var menu = new GenericMenu();
                    if (usedComponents != null)
                    {
                        menu.AddItem(new GUIContent("Delete"), false, () => {
                            RemoveComponent((DataConfigEditor)editor, usedComponents, source, type, noFields);
                            editor.Save();
                            BuildInspectorProperties(editor, usedComponents, source, container, noFields);
                        });

                        menu.AddItem(new GUIContent("Copy JSON"), false, () => {
                            var instance = itCopy.GetValue();
                            var json     = JsonUtility.ToJson(instance, true);
                            EditorGUIUtility.systemCopyBuffer = json;
                        });
                    }

                    editor.OnComponentMenu(menu, idx);
                    menu.ShowAsContext();
                }, i);

                if (type != null && usedComponents?.Contains(type) == false)
                {
                    usedComponents?.Add(type);
                }
                if (type == null)
                {
                    var label = new UnityEngine.UIElements.Label("MISSING: " + iterator.managedReferenceFullTypename);
                    element.name = "missing";
                    label.AddToClassList("inner-element");
                    label.AddToClassList("missing-label");
                    element.Add(label);
                }
                else if (iterator.hasVisibleChildren == false || noFields == true)
                {
                    var horizontal = new UnityEngine.UIElements.VisualElement();
                    horizontal.AddToClassList("inner-element");
                    horizontal.AddToClassList("no-fields-container");
                    element.name = type.Name;

                    var toggle = new UnityEngine.UIElements.Toggle();
                    toggle.AddToClassList("no-fields-toggle");
                    toggle.SetEnabled(false);
                    toggle.SetValueWithoutNotify(true);
                    horizontal.Add(toggle);

                    var label = new UnityEngine.UIElements.Label(GUILayoutExt.GetStringCamelCaseSpace(type.Name));
                    label.AddToClassList("no-fields-label");
                    horizontal.Add(label);

                    element.Add(horizontal);
                }
                else
                {
                    var label = GUILayoutExt.GetStringCamelCaseSpace(type.Name);
                    if (iterator.hasVisibleChildren == true)
                    {
                        var childs = iterator.Copy();
                        //var height = EditorUtilities.GetPropertyHeight(childs, true, new GUIContent(label));
                        var cnt = EditorUtilities.GetPropertyChildCount(childs);
                        if (cnt == 1 /*&& height <= 22f*/)
                        {
                            iterator.NextVisible(true);
                        }
                    }

                    var propertyField = new PropertyField(iterator.Copy(), label);
                    propertyField.BindProperty(iterator);
                    onBuild?.Invoke(i, propertyField);
                    propertyField.AddToClassList("property-field");
                    propertyField.AddToClassList("inner-element");
                    element.name = type.Name;
                    element.Add(propertyField);
                }

                if (type != null)
                {
                    var helps = type.GetCustomAttributes(typeof(ComponentHelpAttribute), false);
                    if (helps.Length > 0)
                    {
                        var label = new UnityEngine.UIElements.Label(((ComponentHelpAttribute)helps[0]).comment);
                        label.AddToClassList("comment");
                        element.Add(label);
                    }

                    if (typeof(IComponentStatic).IsAssignableFrom(type) == true)
                    {
                        var label = new UnityEngine.UIElements.Label("Static");
                        label.AddToClassList("static-component");
                        element.AddToClassList("has-static-component");
                        element.Add(label);
                    }

                    if (typeof(IComponentShared).IsAssignableFrom(type) == true)
                    {
                        var label = new UnityEngine.UIElements.Label("Shared");
                        label.AddToClassList("shared-component");
                        element.AddToClassList("has-shared-component");
                        element.Add(label);
                    }
                }

                container.Add(element);
                ++i;
            } while (iteratorNext.NextVisible(false) == true && depth <= iteratorNext.depth);
        }
예제 #4
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="minValue">The minimum value in the range to be represented.</param>
        /// <param name="maxValue">The maximum value in the range to be represented.</param>
        /// <param name="minLimit">The minimum value of the slider limit.</param>
        /// <param name="maxLimit">The maximum value of the slider limit.</param>
        public MinMaxSlider(string label, float minValue = 0, float maxValue = kDefaultHighValue, float minLimit = float.MinValue, float maxLimit = float.MaxValue)
            : base(label, null)
        {
            m_MinLimit = float.MinValue;
            m_MaxLimit = float.MaxValue;

            lowLimit  = minLimit;
            highLimit = maxLimit;

            // Can't set to value here, because it could be overriden in a derived type.
            var clampedValue = ClampValues(new Vector2(minValue, maxValue));

            this.minValue = clampedValue.x;
            this.maxValue = clampedValue.y;
            AddToClassList(ussClassName);
            labelElement.AddToClassList(labelUssClassName);
            visualInput.AddToClassList(inputUssClassName);

            pickingMode = PickingMode.Ignore;

            m_DragState = DragState.NoThumb;

            visualInput.pickingMode = PickingMode.Position;
            var trackElement = new VisualElement()
            {
                name = "unity-tracker"
            };

            trackElement.AddToClassList(trackerUssClassName);
            visualInput.Add(trackElement);

            dragElement = new VisualElement()
            {
                name = "unity-dragger"
            };
            dragElement.AddToClassList(draggerUssClassName);
            dragElement.RegisterCallback <GeometryChangedEvent>(UpdateDragElementPosition);
            visualInput.Add(dragElement);

            // For a better handling of the cursor style, children elements are created so that the style is automatic with the uss.
            dragMinThumb = new VisualElement()
            {
                name = "unity-thumb-min"
            };
            dragMaxThumb = new VisualElement()
            {
                name = "unity-thumb-max"
            };
            dragMinThumb.AddToClassList(minThumbUssClassName);
            dragMaxThumb.AddToClassList(maxThumbUssClassName);
            dragElement.Add(dragMinThumb);
            dragElement.Add(dragMaxThumb);

            clampedDragger = new ClampedDragger <float>(null, SetSliderValueFromClick, SetSliderValueFromDrag);
            visualInput.AddManipulator(clampedDragger);

            m_MinLimit = minLimit;
            m_MaxLimit = maxLimit;
            rawValue   = ClampValues(new Vector2(minValue, maxValue));
            UpdateDragElementPosition();
        }
예제 #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);
        }
예제 #6
0
        private VisualElement CloneSetupRecursively(VisualElementAsset root,
                                                    Dictionary <int, List <VisualElementAsset> > idToChildren, CreationContext context)
        {
            VisualElement ve = Create(root, context);

            // 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.classes != null)
            {
                for (int i = 0; i < root.classes.Length; i++)
                {
                    ve.AddToClassList(root.classes[i]);
                }
            }

            if (root.ruleIndex != -1)
            {
                if (inlineSheet == null)
                {
                    Debug.LogWarning("VisualElementAsset has a RuleIndex but no inlineStyleSheet");
                }
                else
                {
                    StyleRule r          = inlineSheet.rules[root.ruleIndex];
                    var       stylesData = new VisualElementStylesData(false);
                    ve.SetInlineStyles(stylesData);

                    s_StylePropertyReader.SetInlineContext(inlineSheet, r, root.ruleIndex);
                    stylesData.ApplyProperties(s_StylePropertyReader, null);
                }
            }

            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);
        }